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 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.

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