Back to h2c, RFC7231 spells out 6.5.15 <https://tools.ietf.org/html/rfc7231#section-6.5.15>. 426 Upgrade Required
The 426 (Upgrade Required) status code indicates that the server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol. The server MUST send an Upgrade header field in a 426 response to indicate the required protocol(s) (Section 6.7 of [RFC7230] <https://tools.ietf.org/html/rfc7230#section-6.7>). Example: HTTP/1.1 426 Upgrade Required Upgrade: HTTP/3.0 Connection: Upgrade Content-Length: 53 Content-Type: text/plain This service requires use of the HTTP/3.0 protocol. This leaves a lot of stuff out from the original RFC2817 definition of 426... 4.2 Mandatory Advertisement A server MAY indicate that a client request can not be completed without TLS using the "426 Upgrade Required" status code, which MUST include an an Upgrade header field specifying the token of the required TLS version. HTTP/1.1 426 Upgrade Required Upgrade: TLS/1.0, HTTP/1.1 Connection: Upgrade The server SHOULD include a message body in the 426 response which indicates in human readable form the reason for the error and describes any alternative courses which may be available to the user. Note that even if a client is willing to use TLS, it must use the operations in Section 3 to proceed; the TLS handshake cannot begin immediately after the 426 response. And then I'm reading a really nonsensical comment in this FAQ... https://http2.github.io/faq/#implementation-questions Can I implement HTTP/2 without implementing HTTP/1.1? "Requests without the h2c upgrade token can be rejected with a 505 (HTTP Version Not Supported) status code that contains the Upgrade header field. Servers that don’t wish to process the HTTP/1.1 response should reject stream 1 with a REFUSED_STREAM error code immediately after sending the connection preface to encourage the client to retry the request over the upgraded HTTP/2 connection." which would be absurd... 6.6.6 <https://tools.ietf.org/html/rfc7231#section-6.6.6>. 505 HTTP Version Not Supported The 505 (HTTP Version Not Supported) status code indicates that the server does not support, or refuses to support, the major version of HTTP that was used in the request message. The server is indicating that it is unable or unwilling to complete the request using the same major version as the client, as described in Section 2.6 of [RFC7230] <https://tools.ietf.org/html/rfc7230#section-2.6>, other than with this error message. The server SHOULD generate a representation for the 505 response that describes why that version is not supported and what other protocols are supported by that server. A 505 is an unrecoverable error, the client isn't expected to do anything with it. I just want to ensure that we do *not* follow this guidance; if the user wants configure httpd to enforce HTTP/2 only on a particular vhost, we should be sending a 426 error always, with an error message explaining exactly why their request is rejected, but giving the user-agent the opportunity to automatically upgrade without presenting the message to the user.
