{"record":{"id":"97997cbef7f25468","repo":"dotnet/aspnetcore","slug":"cannot-refresh-authentication-before-the-connectio","errorCode":null,"errorMessage":"Cannot refresh authentication before the connection is started.","messagePattern":"Cannot refresh authentication before the connection is started\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/ts/signalr/src/HttpConnection.ts","lineNumber":415,"sourceCode":"\n        refreshUrl.searchParams.append(\"id\", connectionToken);\n        return refreshUrl.toString();\n    }\n\n    private _configureAuthenticationRefresh(negotiateResponse: INegotiateResponse): void {\n        this._connectionToken = negotiateResponse.connectionToken;\n        this._connectionUrl = this.baseUrl;\n\n        const authenticationRefreshFeature: IAuthenticationRefreshFeature = {\n            initialTokenLifetimeInSeconds: this._initialTokenLifetimeInSeconds,\n            refreshAuthentication: () => this._refreshAuthentication(),\n        };\n        this.features.authenticationRefresh = authenticationRefreshFeature;\n    }\n\n    private async _refreshAuthentication(): Promise<number | undefined> {\n        if (!this._connectionToken || !this._connectionUrl) {\n            throw new Error(\"Cannot refresh authentication before the connection is started.\");\n        }\n\n        const connectionGeneration = this._connectionGeneration;\n        const headers: {[k: string]: string} = {};\n        const [name, value] = getUserAgentHeader();\n        headers[name] = value;\n\n        const refreshUrl = this._createRefreshUrl(this._connectionUrl, this._connectionToken);\n        this._logger.log(LogLevel.Debug, `Sending authentication refresh request: ${refreshUrl}.`);\n\n        const request: HttpRequest = {\n            content: \"\",\n            headers: { ...headers, ...this._options.headers },\n            timeout: this._options.timeout,\n            withCredentials: this._options.withCredentials,\n        };\n        this._httpClient.markAuthenticationRefreshRequest(request);\n        const response = await this._httpClient.post(refreshUrl, request);","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/SignalR/clients/ts/signalr/src/HttpConnection.ts#L397-L433","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Only call refreshAuthentication after `await hubConnection.start()` has resolved and while `state === HubConnectionState.Connected`.","Guard the call: `if (hub.state === HubConnectionState.Connected) await hub.refreshAuthentication();`.","Let the built-in auto-refresh timer (withAuthenticationRefresh) handle it rather than calling manually."],"exampleFix":"// before\nawait hub.start();\n// ... later, possibly after disconnect\nawait hub.refreshAuthentication();\n\n// after\nif (hub.state === HubConnectionState.Connected) {\n  await hub.refreshAuthentication();\n}","handlingStrategy":"validation","validationCode":"function canRefresh(conn) {\n  return conn.state === HubConnectionState.Connected;\n}\nif (canRefresh(hub)) await hub.refreshAuthentication();","typeGuard":"function isConnectionReadyForRefresh(hub: HubConnection): boolean {\n  return hub.state === HubConnectionState.Connected;\n}","tryCatchPattern":"try { await hub.refreshAuthentication(); }\ncatch (e) {\n  if (/before the connection is started/.test(String(e))) {\n    await hub.start(); // or skip refresh\n    return;\n  }\n  throw e;\n}","preventionTips":["Always check hub.state === Connected before calling refreshAuthentication.","Prefer withAuthenticationRefresh on the builder for auto-refresh scheduling.","Cancel any manual refresh timer in your onclose handler."],"tags":["authentication","lifecycle","refresh","validation"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}