OrchardCMS/OrchardCore · error · Error

'WebSocket' is not supported in your environment.

Error message

'WebSocket' is not supported in your environment.

What it means

HttpConnection._constructTransport throws this when a WebSockets transport is requested but no WebSocket implementation is available in the runtime — i.e. options.WebSocket is null/undefined because the environment (very old browser, restricted sandbox, or Node without a WebSocket polyfill) does not provide the global WebSocket constructor.

Solutions

  1. Allow an additional transport (SSE or LongPolling) by leaving transport unset (auto) so the client falls back.
  2. In Node, provide a WebSocket implementation: options.WebSocket = require('ws').
  3. Upgrade the runtime/browser to one with native WebSocket support.
  4. If WebSockets are blocked by the network, enable SSE/LongPolling on the server and negotiate normally.

Example fix

// before (Node, no global WebSocket)
new signalR.HubConnectionBuilder()
  .withUrl(url, { transport: signalR.HttpTransportType.WebSockets })
  .build();
// after
const WebSocket = require("ws");
new signalR.HubConnectionBuilder()
  .withUrl(url, { WebSocket, transport: signalR.HttpTransportType.WebSockets })
  .build();
Defensive patterns

Strategy: fallback

Validate before calling

function hasWebSocketSupport() {
  return typeof WebSocket !== "undefined";
}
const transport = hasWebSocketSupport()
  ? signalR.HttpTransportType.WebSockets
  : signalR.HttpTransportType.LongPolling;

Type guard

function supportsWebSockets(options) {
  return typeof WebSocket !== "undefined" || options.WebSocket != null;
}

Try / catch

try {
  await connection.start();
} catch (err) {
  if (err.message.includes("'WebSocket' is not supported")) {
    connection = rebuildConnection({ transport: signalR.HttpTransportType.LongPolling });
    await connection.start();
  } else { throw err; }
}

Prevention

When it happens

Trigger: Requesting HttpTransportType.WebSockets explicitly (transport: signalR.HttpTransportType.WebSockets or skipNegotiation: true with WebSockets) in an environment lacking a global WebSocket; running the client in Node.js without injecting options.WebSocket.

Common situations: Node.js server-side SignalR clients before WebSocket globals existed (no WebSocket in older Node); locked-down corporate browsers or WebViews without WebSocket support; custom environments that stripped window.WebSocket.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/6e1561a010fb93d7. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.SignalR/wwwroot/Scripts/signalr.js:2993

                    transportExceptions.push(new FailedToStartTransportError(`${endpoint.transport} failed: ${ex}`, HttpTransportType[endpoint.transport]));
                    if (this._connectionState !== "Connecting" /* ConnectionState.Connecting */) {
                        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."));
    }
    _constructTransport(transport) {
        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}.`);
        }
    }
    _startTransport(url, transferFormat) {
        this.transport.onreceive = this.onreceive;
        if (this.features.reconnect) {
            this.transport.onclose = async (e) => {
                let callStop = false;

View on GitHub (pinned to 4306c0717f)