# 101 Switching Protocols and the WebSocket handshake

> 101 Switching Protocols confirms the server accepted an Upgrade request, typically switching the connection from HTTP/1.1 to WebSocket.

URL: https://yes-seo.com/http-status-codes/101

**101 Switching Protocols** means the server agreed to the client’s request to change protocols on the current connection. Right after the 101, both sides stop speaking HTTP/1.1 and start speaking the new protocol, which in practice is almost always WebSocket.

## How the upgrade works

[RFC 9110, section 15.2.2](https://www.rfc-editor.org/rfc/rfc9110#section-15.2.2) ties 101 to the `Upgrade` header: the server switches only when the client asks, and it must send an `Upgrade` header naming the protocol that takes over. The WebSocket handshake from RFC 6455 is the best-known case:

```
GET /chat HTTP/1.1
Host: app.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=
```

101 belongs to HTTP/1.1. HTTP/2 dropped support for it: WebSockets over HTTP/2 use an extended CONNECT request instead (RFC 8441).

## Why the upgrade fails

- A reverse proxy or load balancer drops the hop-by-hop `Upgrade` and `Connection` headers, so the app sees a normal request and replies 200 or [400](https://yes-seo.com/http-status-codes/400) instead of 101.

- The proxy closes idle connections after its read timeout, cutting live sockets.

- A CDN or hosting plan doesn’t allow WebSockets on that hostname.

For Nginx in front of a Node.js or Python app, forward the headers explicitly:

```
location /ws/ {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;
}
```

## SEO impact

A 101 never applies to the page itself. Crawlers request HTML with ordinary GET requests and get a normal final status. The risk is content: text that only arrives through a WebSocket after the page loads isn’t in the server HTML that many crawlers, and our checkers, read. Put headings, body copy and links in the initial response (see [JavaScript SEO](https://yes-seo.com/glossary/javascript-seo)) and use the socket for live updates. Confirm the page URL itself returns [200](https://yes-seo.com/http-status-codes/200) with the [HTTP status checker](https://yes-seo.com/http-status-checker).

## Frequently asked questions

### Is 101 Switching Protocols an error?

No. It means a protocol upgrade succeeded, usually a WebSocket handshake. In browser DevTools, a working WebSocket connection shows status 101.

### Why does my WebSocket get 200 or 400 instead of 101?

The Upgrade and Connection headers were lost on the way, most often at a reverse proxy or load balancer that isn’t configured for WebSockets. It can also mean the URL isn’t a WebSocket endpoint at all.

### Does HTTP/2 use 101 Switching Protocols?

No. HTTP/2 removed support for 101. Over HTTP/2, WebSockets are opened with an extended CONNECT request defined in RFC 8441.

