App-vNext/Polly · error · ArgumentOutOfRangeException
The number of executions per timespan must be positive.
Error message
The number of executions per timespan must be positive.
What it means
Thrown by RateLimitAsync when the computed per-execution interval (perTimeSpan.Ticks / numberOfExecutions) is less than or equal to TimeSpan.Zero. Because both numberOfExecutions and perTimeSpan are already validated positive, this guard catches integer-division edge cases where perTimeSpan.Ticks is smaller than numberOfExecutions, yielding zero ticks (sub-tick intervals cannot be represented).
Source
Thrown at src/Polly/RateLimit/AsyncRateLimitSyntax.cs:49
{
throw new ArgumentOutOfRangeException(nameof(numberOfExecutions), numberOfExecutions, $"{nameof(numberOfExecutions)} per timespan must be an integer greater than or equal to 1.");
}
if (perTimeSpan <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(perTimeSpan), perTimeSpan, $"{nameof(perTimeSpan)} must be a positive timespan.");
}
if (maxBurst < 1)
{
throw new ArgumentOutOfRangeException(nameof(maxBurst), maxBurst, $"{nameof(maxBurst)} must be an integer greater than or equal to 1.");
}
var onePer = TimeSpan.FromTicks(perTimeSpan.Ticks / numberOfExecutions);
if (onePer <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(perTimeSpan), perTimeSpan, "The number of executions per timespan must be positive.");
}
IRateLimiter rateLimiter = new LockFreeTokenBucketRateLimiter(onePer, maxBurst);
return new AsyncRateLimitPolicy(rateLimiter);
}
}
View on GitHub (pinned to d0e46bdb1e)
Solutions
- Ensure perTimeSpan.Ticks >= numberOfExecutions so the per-execution interval is at least one tick; widen perTimeSpan or reduce numberOfExecutions.
- Reconsider the units: express the rate as executions-per-second with a one-second window.
- Validate the derived onePer interval before constructing the policy.
- If you need sub-tick granularity, the legacy LockFreeTokenBucketRateLimiter cannot represent it - use the v8 Polly.RateLimiting (System.Threading.RateLimiting) package instead.
Example fix
// before // 1 tick / 10 executions = 0 ticks -> throws var p = Policy.RateLimitAsync(10, TimeSpan.FromTicks(1), 10); // after var p = Policy.RateLimitAsync(10, TimeSpan.FromSeconds(1), 10);
Defensive patterns
Strategy: validation
Validate before calling
if (perTimeSpan.Ticks < numberOfExecutions)
throw new ArgumentOutOfRangeException(nameof(perTimeSpan), "perTimeSpan must have at least one tick per execution");
var p = Policy.RateLimitAsync(numberOfExecutions, perTimeSpan, maxBurst); Prevention
- Express rates as executions-per-second with a one-second window to avoid sub-tick math.
- Ensure perTimeSpan.Ticks >= numberOfExecutions before constructing the policy.
- For sub-tick rates, migrate to Polly v8 RateLimiting (System.Threading.RateLimiting).
When it happens
Trigger: Configuring a high numberOfExecutions against a tiny perTimeSpan such that perTimeSpan.Ticks / numberOfExecutions rounds down to zero. Example: RateLimitAsync(1000, TimeSpan.FromMilliseconds(1), burst) - 1ms is 10000 ticks, divided by 1000 = 10 ticks (ok), but TimeSpan.FromTicks(1) / 1000 = 0 ticks triggers it.
Common situations: Aggressive high-rate configs where the desired per-execution cadence is below one tick (~100ns); mis-scaled units (per-second count applied to a per-millisecond window); dynamic config that scales executions up without scaling the window.
Related errors
- perTimeSpan must be a positive timespan.
- perTimeSpan must be a positive timespan.
- The number of executions per timespan must be positive.
- numberOfExecutions per timespan must be an integer greater t
- maxBurst must be an integer greater than or equal to 1.
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/43136196125b23df.
Report an issue: GitHub.