App-vNext/Polly · error · ArgumentOutOfRangeException
seconds
Error message
seconds
What it means
ArgumentOutOfRangeException (ParamName "seconds") is thrown at configuration time by TimeoutAsync(int seconds, Func<Context,TimeSpan,Task,Exception,Task> onTimeoutAsync) when seconds <= 0 (AsyncTimeoutSyntax.cs:56-59). Unlike sibling overloads that call TimeoutValidator.ValidateSecondsTimeout, this overload uses a direct `if (seconds <= 0)` check and throws with the generic message-less constructor. A timeout must be strictly positive.
Source
Thrown at src/Polly/Timeout/AsyncTimeoutSyntax.cs:58
{
TimeoutValidator.ValidateSecondsTimeout(seconds);
return TimeoutAsync(_ => TimeSpan.FromSeconds(seconds), TimeoutStrategy.Optimistic, onTimeoutAsync);
}
/// <summary>
/// Builds an <see cref="AsyncPolicy"/> 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>
/// <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 TimeoutAsync(int seconds, Func<Context, TimeSpan, Task, Exception, Task> onTimeoutAsync)
{
if (seconds <= 0)
{
throw new ArgumentOutOfRangeException(nameof(seconds));
}
return TimeoutAsync(_ => TimeSpan.FromSeconds(seconds), TimeoutStrategy.Optimistic, onTimeoutAsync);
}
/// <summary>
/// Builds an <see cref="AsyncPolicy" /> 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>
/// <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 TimeoutAsync(int seconds, TimeoutStrategy timeoutStrategy, Func<Context, TimeSpan, Task, Task> onTimeoutAsync)
{
TimeoutValidator.ValidateSecondsTimeout(seconds);View on GitHub (pinned to d0e46bdb1e)
Solutions
- Pass a positive integer seconds value, e.g. Policy.TimeoutAsync(30, onTimeoutAsync).
- If the value comes from config, validate it is > 0 before calling and fall back to a sane default.
- For 'no timeout', use the TimeSpan overload with System.Threading.Timeout.InfiniteTimeSpan rather than a negative seconds value.
Example fix
// before int seconds = int.Parse(config["TimeoutSeconds"]); // 0 when missing var policy = Policy.TimeoutAsync(seconds, onTimeoutAsync); // after int seconds = int.TryParse(config["TimeoutSeconds"], out var s) && s > 0 ? s : 30; var policy = Policy.TimeoutAsync(seconds, onTimeoutAsync);
Defensive patterns
Strategy: validation
Validate before calling
if (seconds <= 0) throw new InvalidOperationException($"Timeout seconds must be > 0, got {seconds}.");
var policy = Policy.TimeoutAsync(seconds, onTimeoutAsync); Type guard
static bool IsValidSeconds(int seconds) => seconds > 0;
Prevention
- Bound config-sourced seconds to a sane default (> 0) when parsing fails or yields zero.
- Use the TimeSpan overload with System.Threading.Timeout.InfiniteTimeSpan to express 'no timeout' rather than a negative int.
- Add a unit test asserting the configured timeout is positive.
When it happens
Trigger: Policy.TimeoutAsync(0, onTimeoutAsync) or Policy.TimeoutAsync(-1, onTimeoutAsync) — any seconds value that is zero or negative.
Common situations: A timeout value read from configuration that defaulted to 0 when the key was missing; arithmetic that produces zero or a negative number (e.g. subtraction of buffers); passing Timeout.Infinite (a negative int) by mistake into the seconds overload instead of the TimeSpan overload.
Related errors
- timeoutProvider
- Value must be greater than or equal to zero.
- action
- No predicates were configured. There must be at least one pr
- {PrimaryMessage}\nValidation Errors:\n{error.ErrorMessage}
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/18c268788860e1de.
Report an issue: GitHub.