Código de status HTTP · Informativos (1xx)
101 Switching Protocols
O 101 Switching Protocols significa que o servidor aceitou o pedido de Upgrade do cliente e a conexão passa a falar outro protocolo. Na prática ele aparece toda vez que o navegador abre um WebSocket: o 101 é o fim bem-sucedido do aperto de mão, não um erro.
| Classe | 1xx, Informativos |
|---|---|
| Definido em | RFC 9110 §15.2.2 |
| Pode ir para o cache por padrão | Não |
| Pode repetir o pedido | Não se aplica; depois do 101 a conexão passa a falar o novo protocolo |
| Cabeçalhos relevantes |
|
O que significa o 101
A RFC 9110, seção 15.2.2, exige que o servidor inclua um cabeçalho Upgrade com o protocolo que assume a conexão. No WebSocket (RFC 6455) o navegador envia Upgrade: websocket, Connection: Upgrade e uma Sec-WebSocket-Key aleatória; o servidor responde 101 com Sec-WebSocket-Accept, um hash dessa chave. Depois da linha em branco que encerra o 101, não passa mais HTTP naquela conexão TCP.
O mecanismo é do HTTP/1.1. O HTTP/2 não usa o 101 (RFC 9113, seção 8.6), e WebSockets sobre HTTP/2 usam um CONNECT estendido (RFC 8441). Por isso um proxy reverso precisa falar HTTP/1.1 com o backend para o upgrade passar.
Quando usar
- Deixe a biblioteca de WebSocket enviar; escrever o aperto de mão na mão exige calcular o Sec-WebSocket-Accept e é fácil errar.
- Coloque o endpoint de WebSocket num caminho próprio (/ws) para que as regras de upgrade do proxy valham só ali.
Causas comuns
Se você está visitando o site
- Um chat, placar ao vivo ou painel nunca atualiza: um proxy corporativo, VPN ou antivírus está bloqueando upgrades de WebSocket na sua rede.
Se você administra o servidor
- O aperto de mão volta 200, 400 ou 404 em vez de 101: o nginx ou outro proxy descartou os cabeçalhos Upgrade e Connection, que são salto a salto e não são repassados por padrão.
- O socket abre com 101 e cai depois de exatos 60 segundos sem tráfego: o nginx fecha conexões ociosas após o proxy_read_timeout, que é 60s por padrão.
Como resolver
Se você está visitando o site
- Teste outra rede ou desative a VPN ou a inspeção HTTPS do antivírus e recarregue a página.
Se você administra o servidor
- No nginx, defina proxy_http_version 1.1 e repasse Upgrade e Connection de forma explícita, como no exemplo abaixo.
- Envie frames de ping a cada 20 ou 30 segundos, ou aumente o proxy_read_timeout no location do /ws.
Como enviar um 101
Route handlers do Next.js não conseguem assumir o socket, então não respondem a um upgrade; rode o servidor de WebSocket como processo separado ou num servidor customizado.
import { WebSocketServer } from 'ws';
const server = app.listen(3000);
const wss = new WebSocketServer({ noServer: true });
// ws writes "101 Switching Protocols" and Sec-WebSocket-Accept for you
server.on('upgrade', (req, socket, head) => {
if (req.url !== '/ws') return socket.destroy();
wss.handleUpgrade(req, socket, head, (ws) => {
ws.send('connected');
});
});// github.com/gorilla/websocket
var upgrader = websocket.Upgrader{}
mux.HandleFunc("GET /ws", func(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil) // sends 101 Switching Protocols
if err != nil {
return // Upgrade already wrote an HTTP error response
}
defer conn.Close()
conn.WriteMessage(websocket.TextMessage, []byte("connected"))
})from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def ws_endpoint(websocket: WebSocket):
await websocket.accept() # the server sends 101 Switching Protocols
await websocket.send_text("connected")location /ws {
proxy_pass http://app;
proxy_http_version 1.1; # 101 only exists in HTTP/1.1
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 1h; # default 60s kills idle sockets
}Costuma ser confundido com
- 101 vs 426
- O 426 Upgrade Required é o servidor exigindo a troca de protocolo; o 101 é o servidor aceitando uma troca pedida pelo cliente.
- 101 vs 200
- Um 200 no aperto de mão do WebSocket indica que algo ignorou o Upgrade e serviu uma página normal, então o socket falha.
Perguntas frequentes
- Status 101 na aba Rede do navegador é erro?
- Não. Uma linha de WebSocket com status 101 indica que o aperto de mão deu certo. As mensagens trocadas depois aparecem nessa mesma linha, na aba Mensagens ou Resposta, conforme o navegador.
- Por que meu WebSocket recebe 200 ou 400 em vez de 101?
- Quase sempre um proxy reverso não está repassando os cabeçalhos Upgrade e Connection, e o backend recebe um GET comum. No nginx, inclua proxy_http_version 1.1 e as duas linhas proxy_set_header para Upgrade e Connection.
- O HTTP/2 usa o 101 Switching Protocols?
- Não. A RFC 9113 diz que o HTTP/2 não usa o 101. WebSockets sobre HTTP/2 abrem com um CONNECT estendido, definido na RFC 8441, e muitos servidores simplesmente mantêm o WebSocket em HTTP/1.1.
Revisado em por Arielton Oberek.