We're probably wandering a little off topic and may be talking about different things, but the practical limit of data (list of values, max 255 bytes each) under a single TXT entry (e.g. a CNAME target) is purported to be around 4K, but in practise varies between 1K and 64K depending on the DNS service, with queries having to resort to TCP. An acme challenge value is about 44 bytes.
So if you are stuffing a single target TXT record with multiple values you'll start seeing implementation limits after multiple entries. The DNS management APIs themselves vary and usually invoke paging at some arbitrary cutoff like 10 or 100 values, which some clients will handle and some won't.
You would not have more than one value in the canonical TXT RR at any one time. The record data is removed during cleanup after the challenge is completed, at least by any well designed ACME client. When I referred to collision, I meant simultaneous challenges by different clients, which would lead to conflict over use of the RR.
We may have different expectations of how the DNS RR is modified. I expect the record to only ever contain the contents of one client challenge at any given time. My collision scenario would require Client 1 to populate the RR and Client 2 to overwrite it before Client 1 was finished using it.
The fun part is when you have certs with multiple domains, some of which may be wildcards, and possibly multiple client instance renewing certs are roughly the same time.
This is all fairly hypothetical but my comment was just that there are relevant limits I could easily hit (even in one cert with 100 san) by dedicating one canonical TXT record as auth for everything. Yes, if you manage your client interactions carefully it will work well enough.
Yes, the general approach of keep the last value plus your new value is enough for singular wildcard+domain validations.
There is some code however that seems to have some limit with 100 incorrect TXT RRs, but I'm not entirely sure how it works. I REAALLLLLYY have a distaste for the Go language, for me it's not intuitive and hard to interpret if you don't really know the language intimate:
Lines 76 to 81 seem to loop the found TXT RRs to check if one of them is valid. If a valid one is found, the function returns success. But after that, there is some code doing some stuff with invalidRecord and some kind of limit of 100? I'm not sure but if I interpret it correctly it simply shows all the first 100 if there are more than 100 TXT RRs. If there's only one, it only shows that single one. And if its between 1 and 100 it will only show the first one with just "..and X more".. No clue why that limit of 100 is there..
But overall it seems there isn't a maximum of TXT RRs you're allowed to have other than technical DNS protocol limitations.
This is not it, because if a valid TXT was found earlier in the code at line 77, the whole if len(invalidRecord) > 100 doesn't even come into play.
Ah yes, I think you're correct. I incorrectly tought the len() > 100 check was checking the amount of TXT RRs, but indeed it's just checking the length of the first incorrect TXT RR..