{"record":{"id":"29bf11ad972ce250","repo":"dotnet/aspnetcore","slug":"authentication-refresh-is-only-supported-with-http","errorCode":null,"errorMessage":"Authentication refresh is only supported with HTTP-based connections.","messagePattern":"Authentication refresh is only supported with HTTP-based connections\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/ts/signalr/src/HubConnection.ts","lineNumber":625,"sourceCode":"     */\n    public onreconnected(callback: (connectionId?: string) => void): void {\n        if (callback) {\n            this._reconnectedCallbacks.push(callback);\n        }\n    }\n\n    /** Refreshes the authentication state for this connection.\n     *\n     * @returns A Promise that resolves with the new server-reported token lifetime in seconds, or undefined when the server does not report one.\n     */\n    public async refreshAuthentication(): Promise<number | undefined> {\n        if (this._connectionState !== HubConnectionState.Connected) {\n            throw new Error(\"Cannot refresh authentication when the connection is not active.\");\n        }\n\n        const authenticationRefreshFeature = this.connection.features.authenticationRefresh as IAuthenticationRefreshFeature | undefined;\n        if (!authenticationRefreshFeature) {\n            throw new Error(\"Authentication refresh is only supported with HTTP-based connections.\");\n        }\n\n        let newTokenLifetimeInSeconds: number | undefined;\n        try {\n            newTokenLifetimeInSeconds = await authenticationRefreshFeature.refreshAuthentication();\n        } catch (e) {\n            await this._invokeAuthenticationRefreshFailed(e);\n            throw e;\n        }\n\n        if (this._connectionState === HubConnectionState.Connected &&\n            this.connection.features.authenticationRefresh === authenticationRefreshFeature &&\n            this._isAutoAuthenticationRefreshEnabled() &&\n            isValidAuthenticationTokenLifetime(newTokenLifetimeInSeconds)) {\n            this._scheduleAuthenticationRefresh(newTokenLifetimeInSeconds);\n        }\n\n        await this._invokeAuthenticationRefreshed(newTokenLifetimeInSeconds);","sourceCodeStart":607,"sourceCodeEnd":643,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/SignalR/clients/ts/signalr/src/HubConnection.ts#L607-L643","documentation":"Thrown by HubConnection.refreshAuthentication when `connection.features.authenticationRefresh` is undefined after the state guard passes. The feature is populated only by HTTP-based transports that implement the authenticate-refresh handshake; a custom transport or a non-HTTP connection does not advertise the feature, so manual refresh is unsupported.","triggerScenarios":"Calling refreshAuthentication on a HubConnection whose underlying connection was built with a custom IHttpConnectionOptions/transport that does not set `features.authenticationRefresh`, or using a connection type that does not implement the IAuthenticationRefreshFeature contract.","commonSituations":"Injecting a mock/in-memory transport for testing, using an older transport adapter, or building a custom transport that omits the authenticationRefresh feature.","solutions":["Use the standard HttpConnection (withUrl) which wires the authenticationRefresh feature when the server supports it.","If using a custom transport, implement and attach `features.authenticationRefresh = { refreshAuthentication, initialTokenLifetimeInSeconds }`.","Guard the call with a check that the feature exists before invoking refresh."],"exampleFix":"// before\nawait hubConnection.refreshAuthentication(); // custom transport\n// after - guard the feature\nconst feat = (hubConnection as any).connection?.features?.authenticationRefresh;\nif (feat) await hubConnection.refreshAuthentication();","handlingStrategy":"type-guard","validationCode":"function supportsAuthRefresh(features: any): boolean {\n  return !!features?.authenticationRefresh?.refreshAuthentication;\n}","typeGuard":"function hasAuthRefreshFeature(f: any): f is { refreshAuthentication: () => Promise<number|undefined>; initialTokenLifetimeInSeconds?: number } {\n  return !!f && typeof f.refreshAuthentication === \"function\";\n}","tryCatchPattern":null,"preventionTips":["Use HttpConnection (withUrl) to get the authenticationRefresh feature.","Implement the feature explicitly on custom transports.","Guard the call against missing features."],"tags":["authentication","transport","features","custom-transport"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}