SignalR "WebSocket closed with status code: 1006" in CI
Close code 1006 is an abnormal closure: the connection dropped without a proper close frame. SignalR surfaces it as "WebSocket closed with status code: 1006" when the transport dies mid-stream.
What this error means
The connection's onclose fires (or start() rejects) with "Error: WebSocket closed with status code: 1006 ()". It appears when the server restarts, a proxy times out an idle socket, or the connection is reset.
Error: WebSocket closed with status code: 1006 ().
at WebSocketTransport._webSocket.onclose (node_modules/@microsoft/signalr/dist/cjs/WebSocketTransport.js:...)Common causes
The connection was reset with no close handshake
A server restart, a crash, or a network reset tears down the socket without a close frame, which the client reports as 1006.
An idle-timeout proxy dropped the socket
A reverse proxy that closes idle upgraded connections kills a quiet SignalR socket, producing an abnormal 1006 close.
How to fix it
Enable automatic reconnect and keep-alive
- Configure
withAutomaticReconnect()so a transient 1006 recovers. - Keep the connection active or tune keep-alive so idle proxies do not cut it.
- Assert on the reconnected state rather than the first socket only.
const connection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:5000/hub')
.withAutomaticReconnect()
.build();Raise idle timeouts on the proxy
If a proxy fronts the hub, raise its read/idle timeout so quiet WebSocket connections are not closed as idle.
proxy_read_timeout 300s;
proxy_send_timeout 300s;How to prevent it
- Use withAutomaticReconnect so a transient drop does not fail the test.
- Keep upgraded connections alive under any idle-closing proxy.
- Do not restart the hub while a client connection is open.