Skip to content
Latchkey

Socket.IO "connect_error: websocket error" in CI

When Socket.IO tries to upgrade from polling to a raw WebSocket and the upgrade request is rejected or dropped, engine.io emits connect_error with message "websocket error". Polling may still work, so the symptom is transport-specific.

What this error means

The client fires connect_error with err.message === "websocket error", often only when transports: ["websocket"] forces WebSocket-only and no polling fallback is allowed.

Socket.IO
connect_error Error: websocket error
    at WS.onError (node_modules/engine.io-client/build/cjs/transport.js:...)
    at WebSocket.<anonymous> (node_modules/engine.io-client/build/cjs/transports/websocket.js:...)

Common causes

A proxy or gateway does not forward the Upgrade header

A reverse proxy in front of the test server that does not pass Connection: Upgrade and Upgrade: websocket turns the WebSocket handshake into a plain response and the transport errors.

WebSocket-only transport with a broken upgrade path

Forcing transports: ["websocket"] removes the polling fallback, so any upgrade failure becomes a hard connect_error instead of degrading to polling.

How to fix it

Allow polling as a fallback in tests

Keep both transports so a blocked upgrade degrades gracefully instead of failing the connection.

test.mjs
const client = io(url, { transports: ['polling', 'websocket'] });

Forward Upgrade headers through any proxy

If a proxy sits in front of the server, configure it to pass the WebSocket upgrade headers.

nginx.conf
location /socket.io/ {
  proxy_pass http://app;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
}

How to prevent it

  • Test against the same proxy topology CI uses, not a bare localhost server.
  • Keep polling in the transports list unless you specifically test WebSocket-only.
  • Verify Upgrade headers survive every hop between client and server.

Frequently asked questions

What causes ""connect_error ... websocket error""?
A reverse proxy in front of the test server that does not pass Connection: Upgrade and Upgrade: websocket turns the WebSocket handshake into a plain response and the transport errors.
How do I fix "connect_error ... websocket error"?
Keep both transports so a blocked upgrade degrades gracefully instead of failing the connection.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card