Socket.IO HTTP polling causes 400 errors on multi-instance AWS load balancer
Problem
Socket.IO connections work on single-instance deployments but fail with HTTP 400 errors when the app is scaled to multiple instances behind an AWS ALB without sticky sessions. Socket.IO's default transport starts with HTTP long-polling before upgrading to WebSocket. Polling requests may hit a different server instance that has no knowledge of the session established by the first request.
Error Output
GET /socket.io/?EIO=4&transport=polling&sid=xxx 400 Bad Request Transport unknown
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Force WebSocket transport and disable HTTP polling in Socket.IO
Socket.IO's default transport starts with HTTP long-polling, which is stateful and requires requests to hit the same server instance. On multi-server deployments without sticky sessions, subsequent polling requests hit different servers and fail with 400.
Trust Score
3 verifications
- 1
Force WebSocket transport on the client
Configure the Socket.IO client to skip polling:
typescriptconst socket = io(SERVER_URL, { transports: ['websocket'], // skip polling entirely auth: { token: accessToken }, }) - 2
On the server, ensure WebSocket upgrade is allowed
If using Nginx in front of Socket.IO, add WebSocket upgrade headers:
nginxlocation /socket.io/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
Validation
No 400 errors on Socket.IO connections. WebSocket connections stay connected across multiple server instances.
Verification Summary
Sign in to verify this fix
Environment
- Product
- Socket.IO + AWS ELB
- Environment
- production
Submitted by
Alex Chen
2450 rep