{"record":{"id":"827bec7b9f3dd6c9","repo":"dotnet/aspnetcore","slug":"authentication-refreshbeforeexpirationinmillisecon","errorCode":null,"errorMessage":"Authentication refreshBeforeExpirationInMilliseconds must be a finite number greater than or equal to 0.","messagePattern":"Authentication refreshBeforeExpirationInMilliseconds must be a finite number greater than or equal to 0\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/ts/signalr/src/HubConnection.ts","lineNumber":1033,"sourceCode":"                retryReason,\n            });\n        } catch (e) {\n            this._logger.log(LogLevel.Error, `IRetryPolicy.nextRetryDelayInMilliseconds(${previousRetryCount}, ${elapsedMilliseconds}) threw error '${e}'.`);\n            return null;\n        }\n    }\n\n    private _validateAuthenticationRefreshOptions(): void {\n        if (!this._authenticationRefreshOptions) {\n            return;\n        }\n\n        const refreshBeforeExpirationInMilliseconds = this._authenticationRefreshOptions.refreshBeforeExpirationInMilliseconds;\n        if (refreshBeforeExpirationInMilliseconds !== undefined &&\n            (typeof refreshBeforeExpirationInMilliseconds !== \"number\" ||\n                !Number.isFinite(refreshBeforeExpirationInMilliseconds) ||\n                refreshBeforeExpirationInMilliseconds < 0)) {\n            throw new Error(\"Authentication refreshBeforeExpirationInMilliseconds must be a finite number greater than or equal to 0.\");\n        }\n    }\n\n    private _scheduleAuthenticationRefreshIfNeeded(): void {\n        if (!this._isAutoAuthenticationRefreshEnabled()) {\n            return;\n        }\n\n        const authenticationRefreshFeature = this.connection.features.authenticationRefresh as IAuthenticationRefreshFeature | undefined;\n        const initialTokenLifetimeInSeconds = authenticationRefreshFeature?.initialTokenLifetimeInSeconds;\n        if (isValidAuthenticationTokenLifetime(initialTokenLifetimeInSeconds)) {\n            this._scheduleAuthenticationRefresh(initialTokenLifetimeInSeconds);\n        }\n    }\n\n    private _isAutoAuthenticationRefreshEnabled(): boolean {\n        return !!this._authenticationRefreshOptions && this._authenticationRefreshOptions.enableAutoRefresh !== false;\n    }","sourceCodeStart":1015,"sourceCodeEnd":1051,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/SignalR/clients/ts/signalr/src/HubConnection.ts#L1015-L1051","documentation":"Thrown by HubConnection._validateAuthenticationRefreshOptions when `refreshBeforeExpirationInMilliseconds` is set but is not a finite non-negative number. The guard rejects NaN, Infinity, negatives, and non-number values because they would produce an invalid refresh timer.","triggerScenarios":"Passing an IHttpConnectionOptions.authenticationRefreshOptions object whose `refreshBeforeExpirationInMilliseconds` is `NaN`, `Infinity`, a negative number, a string, or any non-number type when building/starting the HubConnection.","commonSituations":"Reading the value from an env var (string) without parsing, computing it from a division that can be NaN, or copying a config that uses seconds instead of milliseconds.","solutions":["Parse the value to a Number and use Number.isFinite before assigning.","Validate the unit (milliseconds, not seconds) and the sign.","Omit the field entirely if you want the library default."],"exampleFix":"// before\nconst opts = { refreshBeforeExpirationInMilliseconds: process.env.REFRESH_MS };\n// after\nconst ms = Number(process.env.REFRESH_MS);\nconst opts = Number.isFinite(ms) && ms >= 0\n  ? { refreshBeforeExpirationInMilliseconds: ms }\n  : {};","handlingStrategy":"validation","validationCode":"function validRefreshMs(v: unknown): v is number {\n  return typeof v === \"number\" && Number.isFinite(v) && v >= 0;\n}","typeGuard":"function isValidRefreshMs(v: unknown): v is number {\n  return typeof v === \"number\" && Number.isFinite(v) && v >= 0;\n}","tryCatchPattern":null,"preventionTips":["Parse env-provided numbers with Number() and validate.","Confirm units are milliseconds, not seconds.","Omit the field to accept the default."],"tags":["authentication","validation","configuration","numbers"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}