dotnet/aspnetcore · error · Error

HttpConnection.stopConnection(${error}) was called while the

Error message

HttpConnection.stopConnection(${error}) was called while the connection is still in the connecting state.

What it means

Thrown by HttpConnection.stopConnection when the connection-state machine is still in `Connecting` at the moment the underlying transport reports closure. stopConnection is designed to run only from the Connected/Disconnecting states; reaching it during Connecting means the transport fired onclose before the negotiate/connect handshake completed. The library treats this as an unrecoverable internal invariant violation.

Source

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

    }

    private _stopConnection(error?: Error): void {
        this._logger.log(LogLevel.Debug, `HttpConnection.stopConnection(${error}) called while in state ${this._connectionState}.`);

        this.transport = undefined;

        // If we have a stopError, it takes precedence over the error from the transport
        error = this._stopError || error;
        this._stopError = undefined;

        if (this._connectionState === ConnectionState.Disconnected) {
            this._logger.log(LogLevel.Debug, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is already in the disconnected state.`);
            return;
        }

        if (this._connectionState === ConnectionState.Connecting) {
            this._logger.log(LogLevel.Warning, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is still in the connecting state.`);
            throw new Error(`HttpConnection.stopConnection(${error}) was called while the connection is still in the connecting state.`);
        }

        this._connectionGeneration++;

        if (this._connectionState === ConnectionState.Disconnecting) {
            // A call to stop() induced this call to stopConnection and needs to be completed.
            // Any stop() awaiters will be scheduled to continue after the onclose callback fires.
            this._stopPromiseResolver();
        }

        if (error) {
            this._logger.log(LogLevel.Error, `Connection disconnected with error '${error}'.`);
        } else {
            this._logger.log(LogLevel.Information, "Connection disconnected.");
        }

        if (this._sendQueue) {
            this._sendQueue.stop().catch((e) => {

View on GitHub (pinned to 3600ca084e)

Solutions

  1. Inspect the `error` argument carried in the message — it names the underlying transport failure that caused the early close.
  2. Verify the negotiate endpoint is reachable and returns 200 with a valid negotiate response before the transport connects.
  3. Ensure your access-token factory resolves cleanly and does not throw during connect.
  4. Avoid calling connection.stop() before the start() promise has settled when running on flaky networks.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await hubConnection.start();
} catch (e) {
  if (e instanceof Error && /stopConnection.*connecting state/i.test(e.message)) {
    // inspect underlying cause, retry with backoff, or surface to user
  } else throw e;
}

Prevention

When it happens

Trigger: The selected transport's `connect` rejects or its `onclose` fires while HttpConnection is still awaiting the initial connect (state === Connecting). Common proxies: a LongPolling/SSE/WebSocket transport whose first request is aborted by the network or server while negotiation is in flight, or an early `stop()` colliding with a failing connect.

Common situations: Server returns 404/401/500 during the /negotiate POST, the access-token factory throws, a proxy resets the connection mid-handshake, or the caller invokes stop() immediately after start() races the connecting promise.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/d3be7fe6954425bd. Report an issue: GitHub.