101 Switching Protocols
The server is switching the connection to the protocol the client asked for in the Upgrade header.
Status
HTTP/1.1 101 Switching Protocols
Details
- Category: 1xx
- Status: Standard. Registered with IANA and defined by a current standards-track RFC.
- Specification: RFC 9110 §15.2.2
- Cacheable: Not cacheable
- Response body: Must not be sent
- Retry: Not applicable
101 is the handshake that turns an ordinary HTTP connection into something else. The client sends Connection: Upgrade plus an Upgrade header naming the target protocol, and a server that agrees replies 101 with the same protocol name. Everything after the blank line following the 101 belongs to the new protocol, not to HTTP.
In practice this is how WebSocket connections start. The client sends Upgrade: websocket with a Sec-WebSocket-Key, the server answers 101 with the derived Sec-WebSocket-Accept, and the socket carries WebSocket frames from then on. HTTP/2 does not use this mechanism: its upgrade path was removed in favor of ALPN negotiation during the TLS handshake.
Headers
- Upgrade: Names the protocol now in use, echoing the client request, e.g. websocket.
- Connection: Must be Upgrade on both the request and the response.
- Sec-WebSocket-Accept: Required for WebSocket upgrades: the base64 SHA-1 of the client key plus the WebSocket GUID.
Common causes
- A WebSocket client opened a connection and the server accepted the upgrade.
- A client requested an HTTP/1.1 to HTTP/2 upgrade against a server that still supports the prior-knowledge upgrade path.
- A tunnel-style protocol negotiated over HTTP, such as some remote desktop and terminal gateways.
How to fix it
As the client
- Stop parsing the byte stream as HTTP once the 101 header block ends. The next bytes are frames of the new protocol.
- Verify Sec-WebSocket-Accept against the key you sent before trusting the connection.
- If you get a 400 or 426 instead, the server does not support the upgrade on that path. Check the URL and any required subprotocol header.
As the server
- Only send 101 for a protocol you actually implement, and echo it in the Upgrade header.
- Make sure every proxy and load balancer in front of the app forwards Upgrade and Connection headers, or the handshake dies before it reaches you.
- Set an idle timeout appropriate for long-lived sockets rather than the default request timeout.
Examples
GET /socket HTTP/1.1 Host: realtime.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Notes for proxy users
Upgrades only survive a proxy that is explicitly WebSocket aware. HTTP proxies that terminate and re-issue requests will strip Connection and Upgrade as hop-by-hop headers, and the handshake fails with a plain 200 or 400. For proxied automation, tunnel WebSocket traffic with CONNECT rather than relying on header forwarding.