dotnet/aspnetcore · error · Error

Cannot refresh authentication before the connection is start

Error message

Cannot refresh authentication before the connection is started.

What it means

Thrown at HttpConnection.ts:415 inside _refreshAuthentication when either `_connectionToken` or `_connectionUrl` is falsy. Both are set during _configureAuthenticationRefresh which only runs after a successful negotiate; if they are missing the connection never completed its start sequence, so there is no valid refresh endpoint to POST to.

Source

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

        refreshUrl.searchParams.append("id", connectionToken);
        return refreshUrl.toString();
    }

    private _configureAuthenticationRefresh(negotiateResponse: INegotiateResponse): void {
        this._connectionToken = negotiateResponse.connectionToken;
        this._connectionUrl = this.baseUrl;

        const authenticationRefreshFeature: IAuthenticationRefreshFeature = {
            initialTokenLifetimeInSeconds: this._initialTokenLifetimeInSeconds,
            refreshAuthentication: () => this._refreshAuthentication(),
        };
        this.features.authenticationRefresh = authenticationRefreshFeature;
    }

    private async _refreshAuthentication(): Promise<number | undefined> {
        if (!this._connectionToken || !this._connectionUrl) {
            throw new Error("Cannot refresh authentication before the connection is started.");
        }

        const connectionGeneration = this._connectionGeneration;
        const headers: {[k: string]: string} = {};
        const [name, value] = getUserAgentHeader();
        headers[name] = value;

        const refreshUrl = this._createRefreshUrl(this._connectionUrl, this._connectionToken);
        this._logger.log(LogLevel.Debug, `Sending authentication refresh request: ${refreshUrl}.`);

        const request: HttpRequest = {
            content: "",
            headers: { ...headers, ...this._options.headers },
            timeout: this._options.timeout,
            withCredentials: this._options.withCredentials,
        };
        this._httpClient.markAuthenticationRefreshRequest(request);
        const response = await this._httpClient.post(refreshUrl, request);

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Only call refreshAuthentication after `await hubConnection.start()` has resolved and while `state === HubConnectionState.Connected`.
  2. Guard the call: `if (hub.state === HubConnectionState.Connected) await hub.refreshAuthentication();`.
  3. Let the built-in auto-refresh timer (withAuthenticationRefresh) handle it rather than calling manually.

Example fix

// before
await hub.start();
// ... later, possibly after disconnect
await hub.refreshAuthentication();

// after
if (hub.state === HubConnectionState.Connected) {
  await hub.refreshAuthentication();
}
Defensive patterns

Strategy: validation

Validate before calling

function canRefresh(conn) {
  return conn.state === HubConnectionState.Connected;
}
if (canRefresh(hub)) await hub.refreshAuthentication();

Type guard

function isConnectionReadyForRefresh(hub: HubConnection): boolean {
  return hub.state === HubConnectionState.Connected;
}

Try / catch

try { await hub.refreshAuthentication(); }
catch (e) {
  if (/before the connection is started/.test(String(e))) {
    await hub.start(); // or skip refresh
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `hubConnection.refreshAuthentication()` before `start()` has resolved; calling it after the connection was closed (stopConnection clears _connectionToken at line 652); a transport that skipped negotiate and never set the refresh feature.

Common situations: Auto-refresh timer firing on a connection that disconnected just before the timer elapsed; calling refreshAuthentication in app code without awaiting start(); a custom IConnection that doesn't implement the authenticationRefresh feature.

Understand the failure class

Related errors


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