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.
Hop-by-hop header
The Upgrade header is hop-by-hop, meaning each intermediary (proxy, load balancer, CDN) processes the header independently. Intermediaries are not required to forward the header. A reverse proxy sitting between client and server often terminates the upgrade request and establishes a separate connection to the backend.
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 common scenario: a server demands HTTPS
before serving a confidential resource, returning
426 with Upgrade: TLS/1.0 and a
Connection header containing the
Upgrade token. The client then initiates a TLS
connection.
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 crafts 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.
Wait for server confirmation
Clients handling untrusted data sources must
not send optimistic data on an HTTP/1.1
connection. Wait for 101 (Upgrade) or a
2xx response (CONNECT) before
forwarding any new-protocol traffic.
Sending Connection: close is an alternative
safeguard preventing subsequent request
smuggling on the same connection.
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.0
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.
Note
A 426 response is distinct from a 301 or 308 redirect to an HTTPS URL. Redirects instruct the client to re-request at a new location. A 426 tells the client to change the protocol on the current connection. In practice, HTTPS redirects are far more common than 426 responses for enforcing TLS.
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 this
mechanism because the approach was
never widely deployed. The h2c token must not be
sent by clients or selected by servers.
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 |
websocket-over-http/2-and-http/3- because-[[2">HTTP/2 lacks the Upgrade mechanism, WebSocket connections over HTTP/2 use the extended CONNECT method. The server advertises support through theSETTINGS_ENABLE_CONNECT_PROTOCOL setting, and the
client sends a CONNECT request with :protocol
set to websocket. The same approach extends to
HTTP/3.
WebSocket multiplexing The extended CONNECT method allows WebSocket traffic to share a single TCP connection (HTTP/2) or QUIC connection (HTTP/3) with regular HTTP streams, benefiting from multiplexing and flow control. See also
Last updated: April 4, 2026
|