HangfireIO/Hangfire · error · ArgumentOutOfRangeException

HeartbeatInterval must be either non-negative and equal to o

Error message

HeartbeatInterval must be either non-negative and equal to or less than {ServerWatchdog.MaxHeartbeatInterval.Hours} hours

What it means

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.

Source

Thrown at src/Hangfire.Core/BackgroundJobServerOptions.cs:137

            set
            {
                if (value < TimeSpan.Zero || value.TotalMilliseconds > Int32.MaxValue)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), $"SchedulePollingInterval must be non-negative and either equal to or less than {Int32.MaxValue} milliseconds");
                }

                _schedulePollingInterval = value;
            }
        }

        public TimeSpan HeartbeatInterval
        {
            get { return _heartbeatInterval; }
            set
            {
                if (value < TimeSpan.Zero || value > ServerWatchdog.MaxHeartbeatInterval)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), $"HeartbeatInterval must be either non-negative and equal to or less than {ServerWatchdog.MaxHeartbeatInterval.Hours} hours");
                }
                _heartbeatInterval = value;
            }
        }

        public TimeSpan ServerCheckInterval
        {
            get { return _serverCheckInterval; }
            set
            {
                if (value < TimeSpan.Zero || value > ServerWatchdog.MaxServerCheckInterval)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), $"ServerCheckInterval must be either non-negative and equal to or less than {ServerWatchdog.MaxServerCheckInterval.Hours} hours");
                }
                _serverCheckInterval = value;
            }
        }

View on GitHub (pinned to c236dd0f93)

Solutions

  1. Use a non-negative TimeSpan no greater than ServerWatchdog.MaxHeartbeatInterval (the default is BackgroundProcessingServerOptions.DefaultHeartbeatInterval).
  2. Clamp the bound value: options.HeartbeatInterval = TimeSpan.FromTicks(Math.Clamp(ts.Ticks, 0, ServerWatchdog.MaxHeartbeatInterval.Ticks)).
  3. Leave the property unset to keep the default.
  4. Validate the configured value at startup.

Example fix

// before
options.HeartbeatInterval = TimeSpan.FromHours(12); // exceeds MaxHeartbeatInterval

// after
options.HeartbeatInterval = BackgroundProcessingServerOptions.DefaultHeartbeatInterval; // safe default
Defensive patterns

Strategy: validation

Validate before calling

TimeSpan Sanitize(TimeSpan ts) =>
    ts >= TimeSpan.Zero && ts <= ServerWatchdog.MaxHeartbeatInterval ? ts : BackgroundProcessingServerOptions.DefaultHeartbeatInterval;
options.HeartbeatInterval = Sanitize(parsed);

Type guard

static bool IsValid(TimeSpan ts) => ts >= TimeSpan.Zero && ts <= ServerWatchdog.MaxHeartbeatInterval;

Try / catch

try { options.HeartbeatInterval = parsed; }
catch (ArgumentOutOfRangeException) { options.HeartbeatInterval = BackgroundProcessingServerOptions.DefaultHeartbeatInterval; }

Prevention

When it happens

Trigger: Assigning a negative HeartbeatInterval; assigning a value greater than ServerWatchdog.MaxHeartbeatInterval; binding an out-of-range value from configuration.

Common situations: Tuning heartbeat to reduce storage load but setting it above the watchdog maximum; config typos producing negative values; unit confusion; tests probing boundaries.

Related errors


AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13). Data as JSON: /api/errors/300e21a5fa5094a2. Report an issue: GitHub.