Change:
stops iterating over the candidate ECHConfig values. Upon determining the ClientHelloInner, the client-facing server then <del> forwards the ClientHelloInner to the appropriate backend server, which proceeds as in backend-server.  If the backend server responds with a HelloRetryRequest, the client-facing server forwards it, decrypts the client's second ClientHelloOuter using the procedure in server-hrr, and forwards the resulting second ClientHelloInner.  The client-facing server forwards all other TLS messages between the client and backend server unmodified. </del> <ins> checks that the message includes the "ech_is_inner" extension, omits the "encrypted_client_hello" extension, and does not offer TLS 1.2 or below versions.  If any of these checks fails, the client-facing server MUST abort with an "illegal_parameter" alert. If these checks succeed, the client-facing server then forwards the ClientHelloInner to the appropriate backend server, which proceeds as in backend-server.  If the backend server responds with a HelloRetryRequest, the client-facing server forwards it, decrypts the client's second ClientHelloOuter using the procedure in server-hrr, and forwards the resulting second ClientHelloInner.  The client- facing server forwards all other TLS messages between the client and backend server unmodified. </ins> Otherwise, if all candidate ECHConfig values fail to decrypt the extension, the client-facing server MUST ignore the extension and

Discussion:
We currently have a number of invariants on the ClientHelloInner that the client must follow: ClientHelloInner must include echisinner ClientHelloInner may not offer TLS 1.2 and below ClientHelloInner may not include encryptedclienthello (somewhat implicit from the first rule and section 7) But, syntactically, the client could violate this. How is the server expected to respond? In particular, a shared mode server directly observes all invariants, and it seems a little weird to ask it to send something it knows is inconsistent. But if we say to enforce, we either have a shared/split difference, or we put all the enforcement at the client-facing server (not wrong...) because the backend server doesn't have enough information to check these. If ClientHelloInner lacks echisinner, should the server just accept ECH without reporting the confirmation signal, or should it report an error? If we end up negotiating TLS 1.2 with ClientHelloInner, is that an error or do we just proceed, without reporting the confirmation signal and sending a cleartext certificate? If ClientHelloInner contains another encryptedclienthello extension, one possible implementation strategy would report retry keys, since backend server halves that see encryptedclienthello typically assume the extension wasn't decrypted. Is that correct, or do you omit retry keys? NAME
These are just bugs in the client, so I have no qualms with requiring the server to reject the connection when it can. A split mode server might not see all of this. If the fronting server fails to validate the inner CH, all of this might slip through. Especially when the backend isn't able to require ECH on every connection, which seems plausible. So I think we're OK with hard rejection. Failure here in shared mode requires client bugs and the shared mode server can report those. Failure in split mode might not always be detected, but it requires the same client bugs and a lack of diligence on the part of the fronting server (for this to be detectable, echisinner is all they need to check).