dotnet/aspnetcore · critical · Error

'WebSocket' is not supported in your environment.

Error message

'WebSocket' is not supported in your environment.

What it means

Thrown at HttpConnection.ts:529 inside _constructTransport when the WebSockets transport is selected but `options.WebSocket` is falsy. The constructor (lines 110-116) populates this from the global WebSocket in browsers or the `ws` npm module in Node; if neither is available and the user did not supply one, the transport cannot be built.

Source

Thrown at src/SignalR/clients/ts/signalr/src/HttpConnection.ts:529

                        const message = "Failed to select transport before stop() was called.";
                        this._logger.log(LogLevel.Debug, message);
                        return Promise.reject(new AbortError(message));
                    }
                }
            }
        }

        if (transportExceptions.length > 0) {
            return Promise.reject(new AggregateErrors(`Unable to connect to the server with any of the available transports. ${transportExceptions.join(" ")}`, transportExceptions));
        }
        return Promise.reject(new Error("None of the transports supported by the client are supported by the server."));
    }

    private _constructTransport(transport: HttpTransportType): ITransport {
        switch (transport) {
            case HttpTransportType.WebSockets:
                if (!this._options.WebSocket) {
                    throw new Error("'WebSocket' is not supported in your environment.");
                }
                return new WebSocketTransport(this._httpClient, this._accessTokenFactory, this._logger, this._options.logMessageContent!,
                    this._options.WebSocket, this._options.headers || {});
            case HttpTransportType.ServerSentEvents:
                if (!this._options.EventSource) {
                    throw new Error("'EventSource' is not supported in your environment.");
                }
                return new ServerSentEventsTransport(this._httpClient, this._httpClient._accessToken, this._logger, this._options);
            case HttpTransportType.LongPolling:
                return new LongPollingTransport(this._httpClient, this._logger, this._options);
            default:
                throw new Error(`Unknown transport: ${transport}.`);
        }
    }

    private _startTransport(url: string, transferFormat: TransferFormat): Promise<void> {
        this.transport!.onreceive = this.onreceive;
        if (this.features.reconnect) {

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. In Node, install the `ws` package: `npm install ws` (and `eventsource` if you need SSE).
  2. In a custom runtime, pass an implementation: `new HttpConnection(url, { WebSocket: MyWebSocketImpl })`.
  3. In browsers, ensure you're not running in a context where the global WebSocket was deleted.
  4. Fall back to a different transport: `withUrl(url, { transport: HttpTransportType.LongPolling })`.

Example fix

// Node without ws installed -> throws
// fix: install ws
// npm install ws

// or supply a custom impl
new HubConnectionBuilder()
  .withUrl(url, { transport: HttpTransportType.WebSockets, WebSocket: require('ws') })
  .build();
Defensive patterns

Strategy: validation

Validate before calling

function resolveWebSocketImpl() {
  if (typeof WebSocket !== 'undefined') return WebSocket;
  try { return require('ws'); } catch { return undefined; }
}
const WS = resolveWebSocketImpl();
if (!WS) throw new Error('WebSocket unavailable - install ws or pick another transport');
const options = { transport: HttpTransportType.WebSockets, WebSocket: WS };

Type guard

function isWebSocketCtor(v: unknown): v is { new (url: string): any } {
  return typeof v === 'function';
}

Try / catch

try { await conn.start(transferFormat); }
catch (e) {
  if (/'WebSocket' is not supported/.test(String(e))) {
    // fall back to LongPolling
    return new HttpConnection(url, { ...options, transport: HttpTransportType.LongPolling, WebSocket: undefined }).start(transferFormat);
  }
  throw e;
}

Prevention

When it happens

Trigger: Running in an unusual JS environment without a global WebSocket (older Node without `ws` installed, some embedded runtimes, a worker context); explicitly setting `options.WebSocket = null` or undefined; the `ws` module failing to load in Node (Platform.isNode true but require threw or returned null).

Common situations: Node app where `ws` is not in node_modules; serverless/edge runtime without WebSocket support; bundler that tree-shook the ws require; a test environment (jsdom without WebSocket polyfill) forcing SSE to be skipped.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/5019d18464787640. Report an issue: GitHub.