in-solana by Supanode

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

  1. Idle timeout. Most RPC providers close WebSocket connections after 30-60 seconds of inactivity. If you have no active subscriptions, the connection drops.
  2. Server-side rate limiting. Too many subscriptions or too much data on one connection triggers a forced disconnect.
  3. Network interruption. Temporary network issues between your client and the RPC node.
  4. Provider maintenance. Node restarts or deployments close all active connections.
  5. 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

PreventionDetails
Keep-alive pingsSend every 30 seconds to prevent idle timeout
Reconnection logicExponential backoff starting at 1-3 seconds
Subscription trackingRe-subscribe after reconnection
Multiple connectionsDo not put all subscriptions on one connection
Provider with streaming SLAConsider 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: