- Home
- HTTP Status Codes
- 101 Switching Protocols
Status Code
101 Switching Protocols
The server is switching to a different protocol as requested by the client. Learn about WebSocket upgrades and protocol negotiation.
What is 101 Switching Protocols?
TL;DR: Server agrees to switch protocols (usually HTTP to WebSocket). Connection changes to new protocol after this response.
A 101 Switching Protocols status code means the server agrees to switch to a different protocol that the client requested via the Upgrade header. Think of it like switching from talking on the phone to having a video call—you’re changing the communication method mid-conversation.
This is most commonly used to upgrade from HTTP to WebSocket for real-time bidirectional communication.
When Does This Happen?
You’ll see a 101 Switching Protocols response in these common situations:
1. WebSocket Connection Upgrade
Client wants to establish WebSocket for real-time chat
HTTP → WebSocket
2. HTTP/2 Upgrade (Less Common)
Client requests HTTP/2 over cleartext
HTTP/1.1 → HTTP/2
3. Custom Protocol Upgrade
Application-specific protocol negotiation
HTTP → Custom bidirectional protocol
Example Responses
WebSocket Upgrade Request:
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
```http
**101 Switching Protocols Response:**
```http
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Real-World Example
Imagine you’re building a real-time chat application:
Client Initiates WebSocket Upgrade:
GET /ws/chat HTTP/1.1
Host: chat.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: https://example.com
```http
**Server Accepts Upgrade:**
```http
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
After this exchange, the connection is now a WebSocket. Both client and server can send messages at any time without the request/response pattern of HTTP.
101 vs Other Status Codes
| Code | Meaning | Protocol Change | Use Case |
|---|---|---|---|
| 101 | Switching protocols | Yes | WebSocket, protocol upgrades |
| 100 | Continue | No | Large request body validation |
| 200 | OK | No | Standard successful response |
| 426 | Upgrade Required | No (server demands it) | Force protocol upgrade |
Important Characteristics
Permanent Protocol Switch:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
```text
After 101, the connection no longer uses HTTP. All future data follows the new protocol.
**Must Include Upgrade Header:**
```http
# Client MUST send:
Upgrade: websocket
Connection: Upgrade
# Server MUST echo:
Upgrade: websocket
Connection: Upgrade
No Response Body: The 101 response has no body. After the headers, the connection immediately switches to the new protocol.
Common Mistakes
❌ Using 101 without Upgrade header
HTTP/1.1 101 Switching Protocols
# Missing Upgrade header!
```text
**❌ Sending body with 101 response**
```http
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
{"message": "WebSocket ready"} ← Wrong! No body allowed
❌ Not validating WebSocket handshake
// ❌ Bad: Accept any upgrade request
app.get('/ws', (req, res) => {
res.status(101).end()
})
```javascript
**✅ Correct WebSocket upgrade**
```javascript
// ✅ Good: Proper WebSocket handshake
const crypto = require('crypto')
app.get('/ws', (req, res) => {
const key = req.headers['sec-websocket-key']
const acceptKey = crypto
.createHash('sha1')
.update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
.digest('base64')
res.writeHead(101, {
Upgrade: 'websocket',
Connection: 'Upgrade',
'Sec-WebSocket-Accept': acceptKey
})
})
Best Practices
Validate Upgrade Requests:
app.get('/ws', (req, res) => {
// Check required headers
if (req.headers.upgrade?.toLowerCase() !== 'websocket') {
return res.status(400).send('WebSocket upgrade required')
}
if (!req.headers['sec-websocket-key']) {
return res.status(400).send('WebSocket key required')
}
// Proceed with upgrade...
})
```javascript
**Use WebSocket Libraries:**
```javascript
// Use established libraries instead of manual implementation
const WebSocket = require('ws')
const wss = new WebSocket.Server({
server: httpServer,
path: '/ws'
})
wss.on('connection', (ws) => {
ws.on('message', (data) => {
console.log('received:', data)
})
ws.send('Welcome to WebSocket!')
})
Handle Protocol Negotiation:
// Support multiple sub-protocols
app.get('/ws', (req, res) => {
const requestedProtocols = req.headers['sec-websocket-protocol']?.split(',')
const supportedProtocols = ['chat', 'notifications']
const protocol = requestedProtocols?.find((p) => supportedProtocols.includes(p.trim()))
if (!protocol) {
return res.status(400).send('No supported protocol')
}
// Include selected protocol in response
res.setHeader('Sec-WebSocket-Protocol', protocol.trim())
// ... continue with upgrade
})
```javascript
## Implementation Examples
**Node.js with ws library:**
```javascript
const http = require('http')
const WebSocket = require('ws')
const server = http.createServer()
const wss = new WebSocket.Server({ server })
wss.on('connection', (ws, req) => {
console.log('Client connected from:', req.socket.remoteAddress)
ws.on('message', (message) => {
console.log('Received:', message)
ws.send(`Echo: ${message}`)
})
ws.on('close', () => {
console.log('Client disconnected')
})
})
server.listen(3000)
Python with websockets:
import asyncio
import websockets
async def handler(websocket, path):
async for message in websocket:
print(f"Received: {message}")
await websocket.send(f"Echo: {message}")
start_server = websockets.serve(handler, "localhost", 3000)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
```javascript
**Browser JavaScript:**
```javascript
const ws = new WebSocket('ws://localhost:3000/chat')
ws.onopen = () => {
console.log('Connected')
ws.send('Hello Server!')
}
ws.onmessage = (event) => {
console.log('Received:', event.data)
}
ws.onerror = (error) => {
console.error('WebSocket error:', error)
}
ws.onclose = () => {
console.log('Disconnected')
}
Try It Yourself
Visit our request builder to see protocol upgrades:
- Open browser DevTools Network tab
- Visit a WebSocket demo page
- Watch the initial HTTP request
- See the 101 Switching Protocols response
- Observe WebSocket frames in the WS tab
Related Status Codes
- 100 Continue - Interim response for large uploads
- 426 Upgrade Required - Server requires protocol upgrade
- 200 OK - Standard successful HTTP response
Related Headers
- Upgrade - Specifies protocol to switch to
- Connection - Must be “Upgrade” for protocol switching
- Sec-WebSocket-Key - Client’s WebSocket handshake key
- Sec-WebSocket-Accept - Server’s WebSocket handshake response
Frequently Asked Questions
What does 101 Switching Protocols mean?
A 101 response means the server agrees to switch to a different protocol requested by the client via the Upgrade header. It is most commonly used for upgrading HTTP connections to WebSocket.
How does WebSocket upgrade work?
The client sends an HTTP request with Upgrade: websocket header. If the server supports it, it responds with 101 Switching Protocols and the connection becomes a WebSocket connection.
What protocols can be upgraded with 101?
Common upgrades include HTTP to WebSocket, HTTP/1.1 to HTTP/2, and HTTP to TLS. The Upgrade header specifies the target protocol.
Is 101 used for HTTPS?
No, HTTPS uses TLS which is established before HTTP. The 101 status is for application-layer protocol upgrades like WebSocket, not transport-layer security.