Change:
It MAY attempt to use another server from the DNS results, if one is provided. <ins> Client-facing servers with non-uniform cryptographic configurations across backend origin servers segment the ESNI anonymity set based on these configurations.  For example, if a client-facing server hosts k backend origin servers, and exactly one of those backend origin servers supports a different set of cryptographic algorithms than the other (k - 1) servers, it may be possible to identify this single server based on the contents of the ServerHello as this message is not encrypted. </ins> 6.2. A more serious problem is MITM proxies which do not support this

Discussion:
Addresses .
The initial commit for the padding in the spec gave the reason for the "260" figure (maximum domain + TLS struct overhead). There have been many comments mentioning slightly lower numbers (255, 253, etc). It's subtle enough that the spec should probably detail the reason.
Fixed in .
However, the TLS 1.3 definition is: In the ESNI text, it's not clear how maps to TLS 1.3's routine.
I'm not following what the problem is here: AEAD-Encrypt is a function that takes four arguments, the second of which is a nonce. In TLS 1.3 record encryption, this nonce value is set as described in S 5.3. In ESNI, it is derived via HKDF in the fashion described in S 5.1.1..
I don't doubt that there is a right answer. It wasn't clear to me whether I should mix in a sequence number to (maybe zero?). Otherwise, it made sense. Although it might be quite a bit clearer to define each argument in terms of the TLS 1.3 definition.
In other words, the second argument to in TLS 1.3 is "derived from the sequence number and the clientwriteiv or serverwriteiv". As I read, it wasn't clear to me whether I should do nothing to the existing value, or mix in zero or something. This might be really obvious in some implementations, but it wasn't in the one I'm working on.
You don't do either. The function takes a nonce argument. In TLS 1.3, that argument is computed one way, and in ESNI it is computed another way. These are positional functions and the names in scope at the call site are irrelevant. I think your proposed change would confuse rather than illuminating. I agree with you that adding test vectors would be useful, and if you want to supply some -- though I suggest you wait until the next version -- in a PR, that would be great.
OK, maybe my proposed solution is not the best, but I don't think the status quo is great. I get the point of "These are positional functions and the names in scope at the call site are irrelevant", but that's actually not quite true in TLS, afaik. The names tend to imply input/output treatment.

For example, things called "*iv" are inputs to in TLS 1.3. In some implementations, the input "Initialization Vector (IV)" [RFC4106] might be a different static type from the in the TLS 1.3 definition. That's why I got confused. maybe adjust like so: and then:
I don't see how this argues your point. Again, the names are irrelevant. I don't really see how the implementation types are relevant here. In any case, given the state of the draft and the reasonable likelihood this will change, I think this decision is well within editor discretion.
The TLS spec and the ESNI spec do not have a type system. They do have a serialization spec, and I am not arguing about that. I do think the names could be clearer without inventing a type system. Well, I think this perspective leads to reverse engineering C/C++ implementations, rather than precisely specifying the inputs to functions like AEAD-Encrypt.
Maybe it could say something like "The ClientEncryptedSNI.encrypted_sni value is then computed using the usual TLS 1.3 AEAD, but note that the second argument, 'iv', is not combined with a sequence number:" The reason I found this confusing was that TLS 1.3 doesn't define the "nonce" argument symbolically, but the ESNI draft does define "iv" symbolically. That's fine, but I then had to plumb a new kind of value into the library to allow for this IV, and I wasn't sure if it was right.
I agree with NAME that AEAD-Encrypt is a 4 positional argument function and it shouldn't matter what they're called in the ESNI spec compared to what they're called in RFC 8446. However, from re-reading RFC 8446, I don't see a good definition of the AEAD-Encrypt function. Perhaps it would be better to describe the encryption using the Authenticated Encryption interface described in ?
"AEAD-Encrypt is a 4 positional argument function and it shouldn't matter what they're called in the ESNI spec compared to what they're called in RFC 8446." This is sort of true, but I noticed that the specs use the name of the second argument to imply its input treatment: IV vs nonce.

In that light, I suppose my suggested text might sound redundant, but I think the current document is too concise.
Fixed in .
There is an unstated constraint on deployments. All servers in the same anonymity set need to have the same cryptographic configuration. This means that they choose the same key exchange groups/cipher/etc.. when presented with the same ClientHello. Concretely, servers need to produce the same profile for the ServerHello, because the ServerHello is not encrypted and the form of a ServerHello could be used to split the anonymity set if different servers make different choices.
Discussion in the room in Montreal suggested that this would not be a requirement, but more of the form of an observation and suggestion. That is, the document would note that if cryptographic configuration is not consistent, the anonymity set fractures into as many sets as there are configurations. Then it will recommend (but not require) that uniformity is desirable.