{"record":{"id":"300e21a5fa5094a2","repo":"HangfireIO/Hangfire","slug":"heartbeatinterval-must-be-either-non-negative-and","errorCode":null,"errorMessage":"HeartbeatInterval must be either non-negative and equal to or less than {ServerWatchdog.MaxHeartbeatInterval.Hours} hours","messagePattern":"HeartbeatInterval must be either non-negative and equal to or less than (.+?) hours","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Hangfire.Core/BackgroundJobServerOptions.cs","lineNumber":137,"sourceCode":"            set\n            {\n                if (value < TimeSpan.Zero || value.TotalMilliseconds > Int32.MaxValue)\n                {\n                    throw new ArgumentOutOfRangeException(nameof(value), $\"SchedulePollingInterval must be non-negative and either equal to or less than {Int32.MaxValue} milliseconds\");\n                }\n\n                _schedulePollingInterval = value;\n            }\n        }\n\n        public TimeSpan HeartbeatInterval\n        {\n            get { return _heartbeatInterval; }\n            set\n            {\n                if (value < TimeSpan.Zero || value > ServerWatchdog.MaxHeartbeatInterval)\n                {\n                    throw new ArgumentOutOfRangeException(nameof(value), $\"HeartbeatInterval must be either non-negative and equal to or less than {ServerWatchdog.MaxHeartbeatInterval.Hours} hours\");\n                }\n                _heartbeatInterval = value;\n            }\n        }\n\n        public TimeSpan ServerCheckInterval\n        {\n            get { return _serverCheckInterval; }\n            set\n            {\n                if (value < TimeSpan.Zero || value > ServerWatchdog.MaxServerCheckInterval)\n                {\n                    throw new ArgumentOutOfRangeException(nameof(value), $\"ServerCheckInterval must be either non-negative and equal to or less than {ServerWatchdog.MaxServerCheckInterval.Hours} hours\");\n                }\n                _serverCheckInterval = value;\n            }\n        }\n","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.Core/BackgroundJobServerOptions.cs#L119-L155","documentation":"This ArgumentOutOfRangeException(\"value\", \"HeartbeatInterval must be either non-negative and equal to or less than ServerWatchdog.MaxHeartbeatInterval.Hours hours\") is thrown by the HeartbeatInterval setter of BackgroundJobServerOptions. The value must be non-negative and not exceed ServerWatchdog.MaxHeartbeatInterval (an upper bound enforced by the watchdog). HeartbeatInterval controls how often the server sends a heartbeat to storage so the watchdog knows it is alive.","triggerScenarios":"Assigning a negative HeartbeatInterval; assigning a value greater than ServerWatchdog.MaxHeartbeatInterval; binding an out-of-range value from configuration.","commonSituations":"Tuning heartbeat to reduce storage load but setting it above the watchdog maximum; config typos producing negative values; unit confusion; tests probing boundaries.","solutions":["Use a non-negative TimeSpan no greater than ServerWatchdog.MaxHeartbeatInterval (the default is BackgroundProcessingServerOptions.DefaultHeartbeatInterval).","Clamp the bound value: options.HeartbeatInterval = TimeSpan.FromTicks(Math.Clamp(ts.Ticks, 0, ServerWatchdog.MaxHeartbeatInterval.Ticks)).","Leave the property unset to keep the default.","Validate the configured value at startup."],"exampleFix":"// before\noptions.HeartbeatInterval = TimeSpan.FromHours(12); // exceeds MaxHeartbeatInterval\n\n// after\noptions.HeartbeatInterval = BackgroundProcessingServerOptions.DefaultHeartbeatInterval; // safe default","handlingStrategy":"validation","validationCode":"TimeSpan Sanitize(TimeSpan ts) =>\n    ts >= TimeSpan.Zero && ts <= ServerWatchdog.MaxHeartbeatInterval ? ts : BackgroundProcessingServerOptions.DefaultHeartbeatInterval;\noptions.HeartbeatInterval = Sanitize(parsed);","typeGuard":"static bool IsValid(TimeSpan ts) => ts >= TimeSpan.Zero && ts <= ServerWatchdog.MaxHeartbeatInterval;","tryCatchPattern":"try { options.HeartbeatInterval = parsed; }\ncatch (ArgumentOutOfRangeException) { options.HeartbeatInterval = BackgroundProcessingServerOptions.DefaultHeartbeatInterval; }","preventionTips":["Cap against ServerWatchdog.MaxHeartbeatInterval.","Validate config at startup.","Leave unset to use the default."],"tags":["csharp","hangfire","argumentoutofrangeexception","configuration","watchdog","validation","background-jobs"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}