WebSocket handshake error: 400 Bad Request
ID: communication/websocket-handshake-400-bad-request
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| WebSocket (RFC 6455) | active | — | — | — |
| Node.js 18 | active | — | — | — |
| Python websockets 12.0 | active | — | — | — |
| Nginx 1.24 | active | — | — | — |
Root Cause
The WebSocket handshake fails because the server rejects the upgrade request due to missing or invalid headers, such as a missing 'Sec-WebSocket-Key' or an unsupported 'Origin'.
generic中文
WebSocket 握手失败,因为服务器拒绝升级请求,原因是缺少或无效的标头,例如缺少 'Sec-WebSocket-Key' 或不受支持的 'Origin'。
Official Documentation
https://developer.mozilla.org/en-US/docs/Web/API/WebSocketWorkarounds
-
80% success Inspect and fix the 'Origin' header in the client request. For example, in JavaScript: `const socket = new WebSocket('wss://example.com/socket', { headers: { Origin: 'https://example.com' } });` Ensure the Origin matches the server's allowed list.
Inspect and fix the 'Origin' header in the client request. For example, in JavaScript: `const socket = new WebSocket('wss://example.com/socket', { headers: { Origin: 'https://example.com' } });` Ensure the Origin matches the server's allowed list. -
75% success Add the 'Sec-WebSocket-Key' header manually if the library omits it. In Python with websockets: `import base64, os; key = base64.b64encode(os.urandom(16)).decode(); headers = {'Sec-WebSocket-Key': key}` and pass to the client.
Add the 'Sec-WebSocket-Key' header manually if the library omits it. In Python with websockets: `import base64, os; key = base64.b64encode(os.urandom(16)).decode(); headers = {'Sec-WebSocket-Key': key}` and pass to the client. -
85% success Check the server-side Nginx configuration for WebSocket support: ensure `proxy_set_header Upgrade $http_upgrade;` and `proxy_set_header Connection "upgrade";` are present in the location block.
Check the server-side Nginx configuration for WebSocket support: ensure `proxy_set_header Upgrade $http_upgrade;` and `proxy_set_header Connection "upgrade";` are present in the location block.
中文步骤
Inspect and fix the 'Origin' header in the client request. For example, in JavaScript: `const socket = new WebSocket('wss://example.com/socket', { headers: { Origin: 'https://example.com' } });` Ensure the Origin matches the server's allowed list.Add the 'Sec-WebSocket-Key' header manually if the library omits it. In Python with websockets: `import base64, os; key = base64.b64encode(os.urandom(16)).decode(); headers = {'Sec-WebSocket-Key': key}` and pass to the client.Check the server-side Nginx configuration for WebSocket support: ensure `proxy_set_header Upgrade $http_upgrade;` and `proxy_set_header Connection "upgrade";` are present in the location block.
Dead Ends
Common approaches that don't work:
-
Disable header validation in the WebSocket client library
90% fail
Disabling the WebSocket library's built-in header validation does not fix the missing or invalid headers; the server still requires them for the upgrade.
-
Switch to a different WebSocket client library (e.g., from ws to socket.io)
85% fail
Switching to a different WebSocket library without addressing the header issue just moves the problem; the new library will still fail if the headers are wrong.
-
Increase the WebSocket connection timeout
95% fail
Increasing the timeout does not help because the error is immediate upon handshake, not a timeout issue.