HangfireIO/Hangfire · error · ArgumentException
DelaysInSeconds value must be an array of non-negative numbe
Error message
DelaysInSeconds value must be an array of non-negative numbers.
What it means
The DelaysInSeconds property on AutomaticRetryAttribute lets you specify an explicit per-attempt delay array instead of the default exponential backoff. Each element must be a non-negative integer; a null value is allowed (reverts to default), but an empty array or any negative element throws ArgumentException. This is assignment-time validation on the configuration property.
Source
Thrown at src/Hangfire.Core/AutomaticRetryAttribute.cs:157
}
/// <summary>
/// Gets or sets the delays between attempts.
/// </summary>
/// <value>An array of non-negative numbers.</value>
/// <exception cref="ArgumentNullException">The value in a set operation is null.</exception>
/// <exception cref="ArgumentException">The value contain one or more negative numbers.</exception>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int[] DelaysInSeconds
{
get { lock (_lockObject) { return _delaysInSeconds; } }
set
{
if (value != null)
{
if (value.Length == 0) throw new ArgumentNullException(nameof(value));
if (value.Any(static delay => delay < 0))
throw new ArgumentException(
$@"{nameof(DelaysInSeconds)} value must be an array of non-negative numbers.",
nameof(value));
}
lock (_lockObject) { _delaysInSeconds = value; }
}
}
/// <summary>
/// Gets or sets a function using to get a delay by an attempt number.
/// </summary>
/// <exception cref="ArgumentNullException">The value in a set operation is null.</exception>
[JsonIgnore]
public Func<long, int> DelayInSecondsByAttemptFunc
{
get { lock (_lockObject) { return _delayInSecondsByAttemptFunc;} }
set
{View on GitHub (pinned to c236dd0f93)
Solutions
- Replace negative values with 0 (zero-second delay) for immediate retries, or use positive seconds for real delays.
- Ensure the array is non-empty when non-null — provide at least as many entries as Attempts, or use the default backoff by leaving DelaysInSeconds null.
- Sanitize config arrays before assignment: filter out negatives and guard against empty.
Example fix
// before
[AutomaticRetry(Attempts = 3, DelaysInSeconds = new[]{-1, 5, 10})]
// after
[AutomaticRetry(Attempts = 3, DelaysInSeconds = new[]{0, 5, 10})] Defensive patterns
Strategy: validation
Validate before calling
int[] delays = LoadDelays();
if (delays != null && (delays.Length == 0 || delays.Any(d => d < 0)))
delays = null; // fall back to default backoff
attribute.DelaysInSeconds = delays; Type guard
static bool IsValidDelays(int[] value) =>
value == null || (value.Length > 0 && value.All(d => d >= 0)); Prevention
- Allow null to use the built-in exponential backoff.
- Use 0 (not -1) for an immediate retry with no delay.
- Validate arrays loaded from config before assignment.
When it happens
Trigger: Setting [AutomaticRetry(DelaysInSeconds = new[]{-5, 10})] or DelaysInSeconds = new int[0]. A null assignment is permitted (uses default backoff); only non-null arrays with empty/negative elements throw.
Common situations: Loading delay values from JSON/YAML config that maps missing values to -1 or 0-length arrays; mixing up the order of delays; intending 'no delay' but using -1 instead of 0.
Related errors
- Attempts value must be equal or greater than zero.
- value
- WorkerCount property value should be positive.
- StopTimeout must be either equal to or less than {Int32.MaxV
- ShutdownTimeout must be either equal to or less than {Int32.
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/c0b9be10b59b3588.
Report an issue: GitHub.