Skip to content

Reconnection fails with Node.js v22 native WebSocket: "Received network error or non-101 status code" #592

@markope

Description

@markope

Description

When using autobahn-js in Node.js v22, automatic reconnection fails after the first connection closes. The initial connection works correctly, but all subsequent reconnection attempts fail with the error "Received network error or non-101 status code."

Environment

  • Node.js version: v22.21.0 (also affects v21+)
  • autobahn-js version: 22.11.1
  • ws version: 7.5.6 (also tested with 8.18.0)
  • Operating System: Linux (Docker container)

Root Cause

Node.js v21+ includes a native WebSocket implementation (from undici) as a global object. When autobahn-js detects global.WebSocket, it uses the browser code path instead of the Node.js ws library path. The native WebSocket implementation appears to have issues with reconnection attempts.

Steps to Reproduce

  1. Create a WebSocket connection using autobahn-js in Node.js v22
  2. Configure with max_retries: -1 for automatic reconnection
  3. Wait for the connection to close (e.g., server restart or network issue)
  4. Observe that autobahn logs "auto-reconnecting in Xs .." but the reconnection fails
  5. WebSocket error event fires with message "Received network error or non-101 status code"

Expected Behavior

After the connection closes, autobahn should automatically reconnect using the configured retry settings, just as it does with the ws library.

Actual Behavior

  • Initial connection succeeds ✅
  • Connection closes (code 1006) ✅
  • Autobahn triggers retry timer ✅
  • WebSocket object is created with readyState: 0 (CONNECTING) ✅
  • WebSocket immediately fires onerror with "Received network error or non-101 status code" ❌
  • onopen never fires ❌
  • No connection attempt reaches the server ❌

Diagnostic Logs

[WEBSOCKET DEBUG] ===== create() called =====
[WEBSOCKET DEBUG] URL: ws://server:8080/ws
[WEBSOCKET DEBUG] Creating WebSocket object...
[WEBSOCKET DEBUG] WebSocket object created, readyState: 0
[WEBSOCKET DEBUG] *** websocket.onerror FIRED ***
[WEBSOCKET DEBUG] Error message: Received network error or non-101 status code.
[WEBSOCKET DEBUG] Error target readyState: 0

Workaround

Delete global.WebSocket before creating the autobahn Connection to force it to use the ws library:

// Force autobahn to use 'ws' library instead of native WebSocket
if (typeof global !== 'undefined' && global.WebSocket) {
    delete global.WebSocket;
}

const connection = new autobahn.Connection({
    realm: 'realm1',
    transports: [{ type: 'websocket', url: 'ws://server:8080/ws' }],
    max_retries: -1,
    // ... other options
});

This workaround successfully enables reconnection because the ws library handles it correctly.

Suggested Solutions

  1. Short-term: Add a configuration option to explicitly choose between native WebSocket and ws library
  2. Medium-term: Detect and handle Node.js native WebSocket differently, or add specific logic to work around its reconnection issues
  3. Long-term: Investigate and fix compatibility with Node.js native WebSocket, or document that ws library should be preferred in Node.js environments

Additional Context

The issue appears to be specific to reconnection attempts - the initial connection works fine with native WebSocket. The ws library has been battle-tested and handles reconnections reliably. The error message "Received network error or non-101 status code" suggests the native WebSocket is encountering an issue during the handshake on subsequent connection attempts.

Would appreciate any guidance on whether this is a known issue or if there's a better way to ensure the ws library is used in Node.js environments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions