dotnet/aspnetcore · error · Error
Authentication refresh is only supported with HTTP-based…
Error message
Authentication refresh is only supported with HTTP-based connections.
What it means
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.
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.
Example fix
// before await hubConnection.refreshAuthentication(); // custom transport // after - guard the feature const feat = (hubConnection as any).connection?.features?.authenticationRefresh; if (feat) await hubConnection.refreshAuthentication();
Defensive patterns
Strategy: type-guard
Validate before calling
function supportsAuthRefresh(features: any): boolean {
return !!features?.authenticationRefresh?.refreshAuthentication;
} Type guard
function hasAuthRefreshFeature(f: any): f is { refreshAuthentication: () => Promise<number|undefined>; initialTokenLifetimeInSeconds?: number } {
return !!f && typeof f.refreshAuthentication === "function";
} Prevention
- Use HttpConnection (withUrl) to get the authenticationRefresh feature.
- Implement the feature explicitly on custom transports.
- Guard the call against missing features.
When it happens
Trigger: 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.
Common situations: Injecting a mock/in-memory transport for testing, using an older transport adapter, or building a custom transport that omits the authenticationRefresh feature.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Authentication refreshBeforeExpirationInMilliseconds must…
- Authorization requires a cascading parameter of type Task
- Binary protocols over XmlHttpRequest not implementing…
- Cannot refresh authentication before the connection is…
- Cannot refresh authentication when the connection is not…
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/29bf11ad972ce250.
Report an issue: GitHub.
Appendix: source
Thrown at src/SignalR/clients/ts/signalr/src/HubConnection.ts:625
*/
public onreconnected(callback: (connectionId?: string) => void): void {
if (callback) {
this._reconnectedCallbacks.push(callback);
}
}
/** Refreshes the authentication state for this connection.
*
* @returns A Promise that resolves with the new server-reported token lifetime in seconds, or undefined when the server does not report one.
*/
public async refreshAuthentication(): Promise<number | undefined> {
if (this._connectionState !== HubConnectionState.Connected) {
throw new Error("Cannot refresh authentication when the connection is not active.");
}
const authenticationRefreshFeature = this.connection.features.authenticationRefresh as IAuthenticationRefreshFeature | undefined;
if (!authenticationRefreshFeature) {
throw new Error("Authentication refresh is only supported with HTTP-based connections.");
}
let newTokenLifetimeInSeconds: number | undefined;
try {
newTokenLifetimeInSeconds = await authenticationRefreshFeature.refreshAuthentication();
} catch (e) {
await this._invokeAuthenticationRefreshFailed(e);
throw e;
}
if (this._connectionState === HubConnectionState.Connected &&
this.connection.features.authenticationRefresh === authenticationRefreshFeature &&
this._isAutoAuthenticationRefreshEnabled() &&
isValidAuthenticationTokenLifetime(newTokenLifetimeInSeconds)) {
this._scheduleAuthenticationRefresh(newTokenLifetimeInSeconds);
}
await this._invokeAuthenticationRefreshed(newTokenLifetimeInSeconds);View on GitHub (pinned to 3600ca084e)