# WebSocket handshake error: 400 Bad Request

- **ID:** `communication/websocket-handshake-400-bad-request`
- **Domain:** communication
- **Category:** protocol_error
- **Error Code:** `400`
- **Verification:** ai_generated
- **Fix Rate:** 85%

## 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'.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| WebSocket (RFC 6455) | active | — | — |
| Node.js 18 | active | — | — |
| Python websockets 12.0 | active | — | — |
| Nginx 1.24 | active | — | — |

## Workarounds

1. **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.** (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.
   ```
2. **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.** (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.
   ```
3. **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.** (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.
   ```

## Dead Ends

- **Disable header validation in the WebSocket client library** — 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. (90% fail)
- **Switch to a different WebSocket client library (e.g., from ws to socket.io)** — 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. (85% fail)
- **Increase the WebSocket connection timeout** — Increasing the timeout does not help because the error is immediate upon handshake, not a timeout issue. (95% fail)
