App-vNext/Polly · error · ArgumentOutOfRangeException
seconds
Error message
seconds
What it means
Thrown by the generic TimeoutAsync<TResult>(int seconds, ...) overload when seconds <= 0. The overload hard-codes TimeoutStrategy.Optimistic and forwards to the provider-based overload, but only after guarding seconds. It is a construction-time range check, not a runtime timeout.
Source
Thrown at src/Polly/Timeout/AsyncTimeoutTResultSyntax.cs:63
return TimeoutAsync<TResult>(_ => TimeSpan.FromSeconds(seconds), TimeoutStrategy.Optimistic, onTimeoutAsync);
}
/// <summary>
/// Builds an <see cref="AsyncPolicy{TResult}"/> that will wait asynchronously for a delegate to complete for a specified period of time. A <see cref="TimeoutRejectedException"/> will be thrown if the delegate does not complete within the configured timeout.
/// </summary>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="seconds">The number of seconds after which to timeout.</param>
/// <param name="onTimeoutAsync">An action to call on timeout, passing the execution context, the timeout applied, the <see cref="Task"/> capturing the abandoned, timed-out action, and the captured <see cref="Exception"/>.
/// <remarks>The Task parameter will be null if the executed action responded cooperatively to cancellation before the policy timed it out.</remarks></param>
/// <returns>The policy instance.</returns>
/// <exception cref="ArgumentOutOfRangeException">seconds;Value must be greater than zero.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="onTimeoutAsync"/> is <see langword="null"/>.</exception>
public static AsyncTimeoutPolicy<TResult> TimeoutAsync<TResult>(int seconds, Func<Context, TimeSpan, Task, Exception, Task> onTimeoutAsync)
{
if (seconds <= 0)
{
throw new ArgumentOutOfRangeException(nameof(seconds));
}
return TimeoutAsync<TResult>(_ => TimeSpan.FromSeconds(seconds), TimeoutStrategy.Optimistic, onTimeoutAsync);
}
/// <summary>
/// Builds an <see cref="AsyncPolicy{TResult}"/> that will wait asynchronously for a delegate to complete for a specified period of time. A <see cref="TimeoutRejectedException"/> will be thrown if the delegate does not complete within the configured timeout.
/// </summary>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="seconds">The number of seconds after which to timeout.</param>
/// <param name="timeoutStrategy">The timeout strategy.</param>
/// <param name="onTimeoutAsync">An action to call on timeout, passing the execution context, the timeout applied, and a <see cref="Task"/> capturing the abandoned, timed-out action.
/// <remarks>The Task parameter will be null if the executed action responded cooperatively to cancellation before the policy timed it out.</remarks></param>
/// <returns>The policy instance.</returns>
/// <exception cref="ArgumentOutOfRangeException">seconds;Value must be greater than zero.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="onTimeoutAsync"/> is <see langword="null"/>.</exception>
public static AsyncTimeoutPolicy<TResult> TimeoutAsync<TResult>(int seconds, TimeoutStrategy timeoutStrategy, Func<Context, TimeSpan, Task, Task> onTimeoutAsync)
{View on GitHub (pinned to d0e46bdb1e)
Solutions
- Pass a positive int, e.g. Policy.TimeoutAsync<TResult>(30, onTimeoutAsync).
- Validate the source: ensure the config key exists and parses to > 0 before the call.
- Switch to the TimeSpan overload if you need sub-second or infinite timeouts.
Example fix
// before
Policy.TimeoutAsync<MyResult>(configuredSeconds, onTimeoutAsync); // configuredSeconds == 0
// after
if (configuredSeconds <= 0) throw new InvalidOperationException("timeout misconfigured");
Policy.TimeoutAsync<MyResult>(configuredSeconds, onTimeoutAsync); Defensive patterns
Strategy: validation
Validate before calling
if (seconds <= 0) throw new ArgumentOutOfRangeException(nameof(seconds), "must be > 0"); var policy = Policy.TimeoutAsync<TResult>(seconds, onTimeoutAsync);
Type guard
static bool IsValidSeconds(int s) => s > 0;
Prevention
- Validate config-sourced ints at startup.
- Distinguish seconds from milliseconds when computing the value.
- Prefer the TimeSpan overload when units are ambiguous.
When it happens
Trigger: Calling Policy.TimeoutAsync<TResult>(0, onTimeoutAsync), Policy.TimeoutAsync<TResult>(-1, onTimeoutAsync), or any non-positive int. Commonly hit when seconds is read from config or computed and the value is zero/unset.
Common situations: Configuration value missing or empty (int.Parse returns 0 default for the field); passing a literal 0 during scaffolding; computed value from subtraction that goes negative under load; downstream of a units mismatch (milliseconds vs seconds).
Related errors
- timeout
- onTimeoutAsync
- timeoutProvider
- Value must be greater than zero.
- Value must be greater than or equal to zero.
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/a3a6297344382c2a.
Report an issue: GitHub.