WebSocket connection closed abnormally (1006)
WebSocket close code 1006 means the connection dropped without a proper close handshake. The server did not send a close frame — the TCP connection was lost. This is the most common WebSocket error on Solana.
Common causes
- Idle timeout. Most RPC providers close WebSocket connections after 30-60 seconds of inactivity. If you have no active subscriptions, the connection drops.
- Server-side rate limiting. Too many subscriptions or too much data on one connection triggers a forced disconnect.
- Network interruption. Temporary network issues between your client and the RPC node.
- Provider maintenance. Node restarts or deployments close all active connections.
- Message size exceeded. Some providers limit individual WebSocket message size (typically 256 KB - 1 MB).
How to fix
1. Implement automatic reconnection
Always wrap your WebSocket connection in a reconnection loop:
function createReconnectingWebSocket(url: string) {
let ws: WebSocket;
let subscriptions: Map<string, object> = new Map();
function connect() {
ws = new WebSocket(url);
ws.onopen = () => {
// Re-subscribe to all active subscriptions
for (const [id, params] of subscriptions) {
ws.send(JSON.stringify(params));
}
};
ws.onclose = (event) => {
if (event.code === 1006) {
// Reconnect with exponential backoff
setTimeout(connect, 1000 + Math.random() * 2000);
}
};
ws.onerror = () => {
ws.close();
};
}
connect();
return { ws: () => ws, subscriptions };
}
2. Send keep-alive pings
Prevent idle timeouts by sending periodic pings:
const PING_INTERVAL = 30_000; // 30 seconds
setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.ping();
// Or send a lightweight RPC call
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: "keepalive",
method: "getSlot",
}));
}
}, PING_INTERVAL);
3. Limit subscriptions per connection
Spread subscriptions across multiple connections. A typical safe limit is 100-200 subscriptions per connection, but check with your provider.
How to prevent
| Prevention | Details |
|---|---|
| Keep-alive pings | Send every 30 seconds to prevent idle timeout |
| Reconnection logic | Exponential backoff starting at 1-3 seconds |
| Subscription tracking | Re-subscribe after reconnection |
| Multiple connections | Do not put all subscriptions on one connection |
| Provider with streaming SLA | Consider Supanode streaming for high-reliability data feeds |
FAQ
Why does code 1006 have no reason message? By design. Code 1006 indicates a transport-level failure, not an application-level close. The browser or runtime sets it when the TCP connection is lost without a WebSocket close frame.
How often should I expect 1006 errors? On a good connection with keep-alive pings, you may see one every few hours due to normal provider maintenance. Without keep-alive, expect disconnects every 30-60 seconds of inactivity.
Should I use one connection per subscription? No. Creating too many connections wastes resources and may trigger rate limits. Use one connection for 50-200 subscriptions, with multiple connections for larger workloads.
Error text variants
-
WebSocket connection closed abnormally -
code 1006 -
WebSocket connection failed -
connection reset
Updated: