HangfireIO/Hangfire · error · ArgumentOutOfRangeException

Job expiration check interval cannot be greater than int.Max

Error message

Job expiration check interval cannot be greater than int.MaxValue

What it means

SqlServerStorageOptions.JobExpirationCheckInterval was set to a TimeSpan whose TotalMilliseconds exceeds int.MaxValue (~24.8 days), which is invalid. The property is backed by a timer whose interval is an int, so values beyond that range overflow. An ArgumentOutOfRangeException is thrown.

Source

Thrown at src/Hangfire.SqlServer/SqlServerStorageOptions.cs:133

            {
                if (value <= TimeSpan.Zero)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "Sliding timeout should be greater than zero");
                }

                _slidingInvisibilityTimeout = value;
            }
        }

        public bool PrepareSchemaIfNecessary { get; set; }

        public TimeSpan JobExpirationCheckInterval 
        {
            get { return _jobExpirationCheckInterval; } 
            set {
                if (value.TotalMilliseconds > int.MaxValue)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "Job expiration check interval cannot be greater than int.MaxValue");
                }
                _jobExpirationCheckInterval = value;
            }
        }

        public TimeSpan CountersAggregateInterval { get; set; }

        public int? DashboardJobListLimit { get; set; }
        public TimeSpan TransactionTimeout { get; set; }
        public TimeSpan? CommandTimeout { get; set; }
        public TimeSpan? CommandBatchMaxTimeout { get; set; }
        public TimeSpan InactiveStateExpirationTimeout { get; set; }

        public string SchemaName
        {
            get { return _schemaName; }
            set
            {

View on GitHub (pinned to c236dd0f93)

Solutions

  1. Use a reasonable interval such as TimeSpan.FromHours(1) (the typical default range).
  2. If you want to minimize expiration runs, cap the value below int.MaxValue milliseconds (~24.8 days).
  3. Validate config-sourced values and clamp before assignment.

Example fix

// before
options.JobExpirationCheckInterval = TimeSpan.FromDays(30); // > int.MaxValue ms, throws
// after
options.JobExpirationCheckInterval = TimeSpan.FromHours(1);
Defensive patterns

Strategy: validation

Validate before calling

TimeSpan interval = /* from config */;
if (interval.TotalMilliseconds > int.MaxValue)
    throw new ArgumentOutOfRangeException(nameof(interval), $"JobExpirationCheckInterval must not exceed int.MaxValue ms (~24.8 days).");

options.JobExpirationCheckInterval = interval;

Type guard

static bool IsValidExpirationInterval(TimeSpan value) => value.TotalMilliseconds <= int.MaxValue;

Prevention

When it happens

Trigger: Setting JobExpirationCheckInterval to a value greater than TimeSpan.FromMilliseconds(int.MaxValue) (~24.85 days); accidentally using TimeSpan.MaxValue or a very large duration.

Common situations: Copying a value from a config that expresses the interval in ticks or seconds without conversion; disabling expiration checks by setting an extremely large interval.

Related errors


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