HTTP Protocol Upgrade Mechanism
When an active HTTP/1.1 connection needs to switch to a different protocol, the protocol upgrade mechanism handles the transition using the Upgrade and Connection headers without closing the existing connection. In practice, WebSocket is the primary protocol negotiated through this mechanism.
Usage
A protocol upgrade starts when the client sends
an HTTP/1.1 request with the
Upgrade header listing one or more
desired protocols. The Connection
header must include the Upgrade token because
Upgrade is a hop-by-hop header.
The server is free to ignore the upgrade request. Supporting a protocol does not oblige the server to accept the switch. When the server agrees, the response is 101 Switching Protocols with the selected protocol in the Upgrade header. The original HTTP request continues under the new protocol once the switch completes.
When the server ignores the Upgrade header, a normal HTTP response such as 200 OK is returned and the connection remains on HTTP/1.1.
Client-initiated upgrade
The client adds Upgrade and Connection to a standard HTTP request. Additional protocol-specific headers are included as needed. The server responds with 101 to accept or returns a regular response to decline.
The Upgrade header accepts a comma-separated list of protocol tokens. The order reflects client preference, with the most preferred protocol listed first.
Server-initiated upgrade
A server requiring a protocol change before fulfilling a request responds with 426 Upgrade Required. This informs the client the resource is available only over a different protocol. The response includes an Upgrade header listing the required protocol.
A historical scenario, modeled on the defining
RFC's example: a
server demands in-band TLS before serving a
confidential resource, returning
426 with an Upgrade token naming the TLS layer
and a
Connection header containing the
Upgrade token. The pattern predates universal
HTTPS, where TLS wraps the connection from
the start.
There is no guarantee the server fulfills the request even after a successful upgrade.
WebSocket upgrade
The dominant real-world use of the protocol
upgrade mechanism is establishing
WebSocket connections over HTTP/1.1.
The client sends a GET request with
Upgrade: websocket along with the WebSocket
handshake headers.
Request
GET /chat HTTP/1.1
Host: www.example.re
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://example.re
Response
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
After the server returns 101, subsequent data
flows as WebSocket frames rather than HTTP
messages. The Sec-WebSocket-Key and
Sec-WebSocket-Accept exchange confirms both sides
understand the WebSocket protocol and
prevents intermediary caches from replaying stale
upgrade responses.
Optimistic data risks
Some clients send new-protocol data immediately after requesting an upgrade, before the server responds with 101 Switching Protocols. This optimistic approach reduces latency but creates a request smuggling vulnerability.
If the server rejects the upgrade and returns a normal HTTP response, the optimistic data stays in the connection buffer. An attacker controlling the data source constructs payloads the server interprets as valid HTTP requests. The server processes these as legitimate, letting the attacker issue requests under the client's identity and bypass access controls.
The same risk applies to the CONNECT method when proxy clients forward data from untrusted sources before receiving a 2xx confirmation.
Handling 426 Upgrade Required
When a server responds with 426 Upgrade Required, the client must switch to the protocol specified in the Upgrade header before retrying the request. The response always includes an Upgrade header listing the required protocol.
HTTP/1.1 426 Upgrade Required
Upgrade: TLS/1.3, HTTP/1.1
Connection: Upgrade
A client receiving this response over an unencrypted connection initiates a TLS handshake and retries the request over HTTPS. Misconfigured clients or those unable to support the required protocol fail with an error rather than retrying indefinitely.
HTTP/2, HTTP/3, and protocol negotiation
The protocol upgrade mechanism is specific to HTTP/1.1. HTTP/2 and HTTP/3 do not support the Upgrade header or the 101 status code.
The original HTTP/2 specification
included an upgrade path using the h2c token in
the Upgrade header for cleartext
HTTP/2 connections.
The current HTTP/2 specification deprecated the
Upgrade mechanism and its token because the approach
was never widely deployed. Separately, the h2c
identifier is reserved in the TLS ALPN space and
never appears in a TLS negotiation.
TLS ALPN
Modern HTTP version negotiation relies on TLS Application-Layer Protocol Negotiation (ALPN). During the TLS handshake, the client sends a list of supported protocol identifiers and the server selects one. This negotiation completes within the TLS handshake without adding extra round-trips.
Common ALPN protocol identifiers:
| Identifier | Protocol |
|---|---|
http/1.1 |
HTTP/1.1 |
h2 |
HTTP/2 over TLS |
h3 |
HTTP/3 over QUIC |
WebSocket over HTTP/2 and HTTP/3
Because HTTP/2 lacks the Upgrade
mechanism, WebSocket connections over
HTTP/2 use the extended CONNECT
method. The server advertises support through the
SETTINGS_ENABLE_CONNECT_PROTOCOL setting, and the
client sends a CONNECT request with :protocol
set to websocket. The same approach extends to
HTTP/3.
See also
- RFC 9931: Security Considerations for Optimistic Protocol Transitions in HTTP/1.1
- RFC 9110 Section 7.8: Upgrade
- RFC 7301: TLS ALPN
- Upgrade
- Connection
- 101 Switching Protocols
- 426 Upgrade Required
- WebSocket
- WebSocket Secure
- HTTP connection management
- HTTPS
- HTTP headers