HangfireIO/Hangfire · error · ArgumentException

The QueuePollInterval property value should be positive. Giv

Error message

The QueuePollInterval property value should be positive. Given: {value}.

What it means

SqlServerStorageOptions.QueuePollInterval was set to a negative TimeSpan, which is invalid. The setter checks value != value.Duration() — Duration() returns the absolute value, so any negative TimeSpan triggers ArgumentException. QueuePollInterval controls how frequently the server polls the job queue when it is empty.

Source

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

                }
            }

            return null;
        }

        [Obsolete("TransactionIsolationLevel option is deprecated, please set UseRecommendedIsolationLevel instead. Will be removed in 2.0.0.")]
        public IsolationLevel? TransactionIsolationLevel { get; set; }

        public TimeSpan QueuePollInterval
        {
            get { return _queuePollInterval; }
            set
            {
                var message = $"The QueuePollInterval property value should be positive. Given: {value}.";

                if (value != value.Duration())
                {
                    throw new ArgumentException(message, nameof(value));
                }

                _queuePollInterval = value;
            }
        }

        [Obsolete("Does not make sense anymore. Background jobs re-queued instantly even after ungraceful shutdown now. Will be removed in 2.0.0.")]
        public TimeSpan InvisibilityTimeout { get; set; }

        public TimeSpan? SlidingInvisibilityTimeout
        {
            get { return _slidingInvisibilityTimeout; }
            set
            {
                if (value <= TimeSpan.Zero)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "Sliding timeout should be greater than zero");
                }

View on GitHub (pinned to c236dd0f93)

Solutions

  1. Use a positive TimeSpan value such as TimeSpan.FromSeconds(1) or TimeSpan.FromMilliseconds(500).
  2. If the value comes from configuration, validate or clamp it to TimeSpan.Zero or a small positive minimum before assigning.
  3. Use value.Duration() yourself if you want to tolerate negative input, but prefer fixing the source of the negative value.

Example fix

// before
options.QueuePollInterval = TimeSpan.FromSeconds(myConfigValue); // myConfigValue can be -1
// after — clamp to positive
options.QueuePollInterval = TimeSpan.FromSeconds(Math.Max(0, myConfigValue));
Defensive patterns

Strategy: validation

Validate before calling

TimeSpan interval = /* from config or computation */;
if (interval < TimeSpan.Zero)
    throw new ArgumentOutOfRangeException(nameof(interval), "QueuePollInterval must be non-negative.");

options.QueuePollInterval = interval;

Type guard

static bool IsValidPollInterval(TimeSpan value) => value >= TimeSpan.Zero;

Prevention

When it happens

Trigger: Passing TimeSpan.FromTicks(-1), TimeSpan.FromSeconds(-1), or any negative TimeSpan to the QueuePollInterval setter; computing the interval from a subtraction that can go negative.

Common situations: Configuring poll intervals from dynamic values (e.g., config-driven durations) where a negative number leaks through; copying example code that uses a subtraction without clamping; accidental sign error.

Related errors


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