App-vNext/Polly · error · ArgumentOutOfRangeException
numberOfExecutions per timespan must be an integer greater t
Error message
numberOfExecutions per timespan must be an integer greater than or equal to 1.
What it means
Thrown by RateLimitAsync(int, TimeSpan, int) (the factory-less overload) when numberOfExecutions is less than 1. numberOfExecutions defines how many executions are permitted per perTimeSpan window, so zero or negative values are meaningless. The guard is the first of three sequential config validations.
Source
Thrown at src/Polly/RateLimit/AsyncRateLimitSyntax.cs:32
TimeSpan perTimeSpan) =>
RateLimitAsync(numberOfExecutions, perTimeSpan, 1);
/// <summary>
/// Builds a RateLimit <see cref="AsyncPolicy"/> that will rate-limit executions to <paramref name="numberOfExecutions"/> per the timespan given.
/// </summary>
/// <param name="numberOfExecutions">The number of executions (call it N) permitted per timespan.</param>
/// <param name="perTimeSpan">How often N executions are permitted.</param>
/// <param name="maxBurst">The maximum number of executions that will be permitted in a single burst (for example if none have been executed for a while).
/// This equates to the bucket-capacity of a token-bucket implementation.</param>
/// <returns>The policy instance.</returns>
public static AsyncRateLimitPolicy RateLimitAsync(
int numberOfExecutions,
TimeSpan perTimeSpan,
int maxBurst)
{
if (numberOfExecutions < 1)
{
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.");
}View on GitHub (pinned to d0e46bdb1e)
Solutions
- Set numberOfExecutions to a positive integer that reflects measured throughput, e.g. 100.
- Validate/clamp the config value before passing it: Math.Max(1, parsedValue).
- Distinguish 'disable rate limiting' (do not create the policy at all) from 'zero executions'.
- Add an integration test that constructs the policy with realistic config to catch bad values early.
Example fix
// before var p = Policy.RateLimitAsync(0, TimeSpan.FromSeconds(1), 10); // after var p = Policy.RateLimitAsync(10, TimeSpan.FromSeconds(1), 10);
Defensive patterns
Strategy: validation
Validate before calling
int n = Math.Max(1, parsedNumberOfExecutions); if (n < 1) throw new ArgumentOutOfRangeException(nameof(n)); var p = Policy.RateLimitAsync(n, perTimeSpan, maxBurst);
Prevention
- Validate rate-limit config at startup with an assertion on all three bounds.
- Clamp config-derived values with Math.Max(1, value).
- Treat 'disable rate limiting' as 'skip policy construction', not 'set to 0'.
- Unit-test policy construction with realistic config values.
When it happens
Trigger: Calling Policy.RateLimitAsync(0, ts, burst) or with a negative numberOfExecutions. Common when the value is derived from configuration without clamping.
Common situations: Reading numberOfExecutions from appsettings/environment where it is missing (parses to 0), mis-scaled units (per-second value used as per-minute), or a feature flag disabling a limit by setting it to 0.
Related errors
- perTimeSpan must be a positive timespan.
- maxBurst must be an integer greater than or equal to 1.
- The number of executions per timespan must be positive.
- numberOfExecutions per timespan must be an integer greater t
- perTimeSpan must be a positive timespan.
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/373e072803941eda.
Report an issue: GitHub.