Change:
This value is placed in an "encrypted_server_name" extension. <del> The client MAY either omit the "server_name" extension or provide an innocuous dummy one (this is required for technical conformance with RFC7540; Section 9.2.) </del> <ins> The client MUST place the value of ESNIKeys.public_name in the "server_name" extension.  (This is required for technical conformance with RFC7540; Section 9.2.)  The client MUST NOT send a "cached_info" extension RFC7924 with a CachedObject entry whose CachedInformationType is "cert". 5.1.2. If the server negotiates TLS 1.3 or above and provides an "encrypted_server_name" extension in EncryptedExtensions, the client then processes the extension's "response_type" field: If the value is "esni_accept", the client MUST check that the extension's "nonce" field matches ClientESNIInner.nonce and otherwise abort the connection with an "illegal_parameter" alert. The client then proceeds with the connection as usual, verifying the certificate against the desired name. If the value is "esni_retry_request", the client proceeds with the handshake, verifying the certificate against ESNIKeys.public_name as described in verify-public-name.  If verification or the handshake fails, the client MUST return a failure to the calling application.  It MUST NOT use the retry keys. Otherwise, when the handshake completes successfully with the public name verified, the client MUST abort the connection with an "esni_required" alert.  It then processes the "retry_keys" field from the server's "encrypted_server_name" extension. If one of the values contains a version supported by the client, it can regard the ESNI keys as securely replaced by the server. It SHOULD retry the handshake with a new transport connection, using that value to encrypt the SNI.  The value may only be applied to the retry connection.  The client MUST continue to use the previously-advertised keys for subsequent connections.  This avoids introducing pinning concerns or a tracking vector, should a malicious server present client-specific retry keys to identify clients. If none of the values provided in "retry_keys" contains a supported version, the client can regard ESNI as securely disabled by the server.  As below, it SHOULD then retry the handshake with a new transport connection and ESNI disabled. If the field contains any other value, the client MUST abort the connection with an "illegal_parameter" alert. If the server negotiates an earlier version of TLS, or if it does not provide an "encrypted_server_name" extension in EncryptedExtensions, the client proceeds with the handshake, verifying the certificate against ESNIKeys.public_name as described in verify-public-name.  The client MUST NOT enable the False Start optimization RFC7918 for this handshake.  If verification or the handshake fails, the client MUST return a failure to the calling application.  It MUST NOT treat this as a secure signal to disable ESNI. Otherwise, when the handshake completes successfully with the public name verified, the client MUST abort the connection with an "esni_required" alert.  The client can then regard ESNI as securely disabled by the server.  It SHOULD retry the handshake with a new transport connection and ESNI disabled. [[TODO: Key replacement is significantly less scary than saying that ESNI-naive servers bounce ESNI off.  Is it worth defining a strict mode toggle in the ESNI keys, for a deployment to indicate it is ready for that? ]] Clients SHOULD implement a limit on retries caused by "esni_retry_request" or servers which do not acknowledge the "encrypted_server_name" extension.  If the client does not retry in either scenario, it MUST report an error to the calling application. 5.1.3. When the server cannot decrypt or does not process the "encrypted_server_name" extension, it continues with the handshake using the cleartext "server_name" extension instead (see server- behavior).  Clients that offer ESNI then verify the certificate with the public name, as follows: If the server resumed a session or negotiated a session that did not use a certificate for authentication, the client MUST abort the connection with an "illegal_parameter" alert.  This case is invalid because send-esni requires the client to only offer ESNI- established sessions, and server-behavior requires the server to decline ESNI-established sessions if it did not accept ESNI. The client MUST verify that the certificate is valid for ESNIKeys.public_name.  If invalid, it MUST abort the connection with the appropriate alert. If the server requests a client certificate, the client MUST respond with an empty Certificate message, denoting no client certificate. </ins> <del> If the server does not negotiate TLS 1.3 or above, then the client MUST abort the connection with an "unsupported_version" alert.  If the server does not provide an "encrypted_server_name" extension in EncryptedExtensions, the client MUST abort the connection with an "illegal_parameter" alert.  Moreover, it MUST check that ClientESNIInner.nonce matches the value of the "encrypted_server_name" extension provided by the server, and otherwise abort the connection with an "illegal_parameter" alert. </del> <ins> Note that verifying a connection for the public name does not verify it for the origin.  The TLS implementation MUST NOT report such connections as successful to the application.  It additionally MUST ignore all session tickets and session IDs presented by the server. These connections are only used to trigger retries, as described in handle-server-response.  This may be implemented, for instance, by reporting a failed connection with a dedicated error code. </ins> 5.2. Upon receiving an "encrypted_server_name" extension, the client- <del> facing server MUST first perform the following checks: If it is unable to negotiate TLS 1.3 or greater, it MUST abort the connection with a "handshake_failure" alert. If the ClientEncryptedSNI.record_digest value does not match the cryptographic hash of any known ESNIKeys structure, it MUST abort the connection with an "illegal_parameter" alert.  This is necessary to prevent downgrade attacks.  [[OPEN ISSUE: We looked at ignoring the extension but concluded this was better.]] </del> <ins> facing server MUST check that it is able to negotiate TLS 1.3 or greater.  If not, it MUST abort the connection with a "handshake_failure" alert. If the ClientEncryptedSNI.record_digest value does not match the cryptographic hash of any known ESNIKeys structure, it MUST ignore the extension and proceed with the connection, with the following added behavior: It MUST include the "encrypted_server_name" extension in EncryptedExtensions message with the "response_type" field set to "esni_retry_requested" and the "retry_keys" field set to one or more ESNIKeys structures with up-to-date keys.  Servers MAY supply multiple ESNIKeys values of different versions.  This allows a server to support multiple versions at once. The server MUST ignore all PSK identities in the ClientHello which correspond to ESNI PSKs.  ESNI PSKs offered by the client are associated with the ESNI name.  The server was unable to decrypt then ESNI name, so it should not resume them when using the cleartext SNI name.  This restriction allows a client to reject resumptions in verify-public-name. If the ClientEncryptedSNI.record_digest value does match the cryptographic hash of a known ESNIKeys, the server performs the following checks: </ins> If the ClientEncryptedSNI.key_share group does not match one in the ESNIKeys.keys, it MUST abort the connection with an

Discussion:
(WG email coming shortly.) ESNI has different compatibility characteristics than most TLS extensions. It involves client state, and encrypting the SNI makes the ClientHello unusable for servers that do not have the key or do not implement ESNI. This breaks common rollout and rollback strategies and places strong requirements on DNS/server consistency. This makes deploying ESNI risky for servers. This change aims to reduce these deployment risks. ESNI is much more useful if widely deployed. Moreover, if ESNI is unreliable due to complex requirements on the server, clients will be disincentivized to implement it. The DNS/server consistency requirements also disincentivize rotating keys (section 7.2.5). This change introduces the notion of a "public name" which allows the client to receive authenticated signals from the server that the ESNIKeys are out of sync, so clients can safely repair key mismatches. It also aligns with existing server behavior before ESNI, so partial rollouts and rollbacks can also be handled. The fix for the latter also handles MITM scenarios, replacing the existing client recommendation: The public name notion fixes a bug in that text: an attacker could disable ESNI on all servers, given the existence of any such server.
And, as I write this, I realize I forgot to deal with Stephen's comment on the thread about the middlebox stuff! It's quite late here, so I will reword that tomorrow morning.
Currently, the connect fails when a mismatch occurs. An alternative strategy might be to return a new ESNI key that is then used for a subsequent connection.
How to understand the reliability of the public key from server?
I see that I missed something about disabling. I think that this could be a lot more explicit about the three primary cases that I talk about in the comments below.Looks mostly good, but added some nits and clarification questions.