HangfireIO/Hangfire · error · ArgumentOutOfRangeException
Value should be greater than or equal to TimeSpan.Zero
Error message
Value should be greater than or equal to TimeSpan.Zero
What it means
Thrown by the BackgroundExecutionOptions.WarningThreshold setter (internal) when the assigned TimeSpan is less than TimeSpan.Zero. WarningThreshold governs when Faulted-state recovery is logged at Info vs Debug, so a negative span is invalid.
Source
Thrown at src/Hangfire.Core/Processing/BackgroundExecutionOptions.cs:43
private TimeSpan _stillErrorThreshold;
private Func<int, TimeSpan> _retryDelay;
public BackgroundExecutionOptions()
{
WarningThreshold = TimeSpan.FromSeconds(5);
ErrorThreshold = TimeSpan.FromSeconds(15);
StillErrorThreshold = TimeSpan.FromSeconds(60);
RetryDelay = GetBackOffMultiplier;
}
public string Name { get; set; }
public TimeSpan WarningThreshold
{
get { return _warningThreshold; }
set
{
if (value < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(value), "Value should be greater than or equal to TimeSpan.Zero");
_warningThreshold = value;
}
}
public TimeSpan ErrorThreshold
{
get { return _errorThreshold; }
set
{
if (value < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(value), "Value should be greater than or equal to TimeSpan.Zero");
_errorThreshold = value;
}
}
public TimeSpan StillErrorThreshold
{
get { return _stillErrorThreshold; }
setView on GitHub (pinned to c236dd0f93)
Solutions
- Clamp the value before assignment: `options.WarningThreshold = TimeSpan.FromMilliseconds(Math.Max(0, value.TotalMilliseconds))`.
- Validate parsed config at the boundary and reject/replace negative values with a sane default.
- Default is 5s — only override with a known non-negative value.
Example fix
// before options.WarningThreshold = parsedDelay; // parsedDelay == TimeSpan.FromSeconds(-5) // after options.WarningThreshold = parsedDelay < TimeSpan.Zero ? TimeSpan.FromSeconds(5) : parsedDelay;
Defensive patterns
Strategy: validation
Validate before calling
TimeSpan Safe(TimeSpan v) => v < TimeSpan.Zero ? TimeSpan.FromSeconds(5) : v; options.WarningThreshold = Safe(parsedDelay);
Type guard
static bool IsValidThreshold(TimeSpan v) => v >= TimeSpan.Zero;
Prevention
- Clamp all parsed TimeSpans to >= Zero at the config boundary.
- Reject negative durations in any UI that edits thresholds.
- Keep the default (5s) unless you have a measured reason to change it.
When it happens
Trigger: Assigning options.WarningThreshold to a negative TimeSpan. Reached when configuration parsing produces a negative duration (e.g., parsing a malformed '-5s' string or subtracting offsets).
Common situations: A config binding that maps an empty/invalid string to a negative TimeSpan; arithmetic that subtracts two thresholds and underflows; serialisation round-trip that lost the value.
Related errors
- maxConcurrency
- value
- All the threads should be non-null and in the ThreadState.Un
- execution
- taskScheduler
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/9f752ba594256bc9.
Report an issue: GitHub.