App-vNext/Polly · error · ArgumentOutOfRangeException

maxBurst must be an integer greater than or equal to 1.

Error message

maxBurst must be an integer greater than or equal to 1.

What it means

Thrown by RateLimitTResultSyntax.RateLimit<TResult> when maxBurst is less than 1. The generic overload's token-bucket capacity must be at least one, otherwise no execution could ever be permitted.

Source

Thrown at src/Polly/RateLimit/RateLimitTResultSyntax.cs:78

    public static RateLimitPolicy<TResult> RateLimit<TResult>(
        int numberOfExecutions,
        TimeSpan perTimeSpan,
        int maxBurst,
        Func<TimeSpan, Context, TResult>? retryAfterFactory)
    {
        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.");
        }

        IRateLimiter rateLimiter = new LockFreeTokenBucketRateLimiter(onePer, maxBurst);

        return new RateLimitPolicy<TResult>(rateLimiter, retryAfterFactory);
    }
}

View on GitHub (pinned to d0e46bdb1e)

Solutions

  1. Set maxBurst to at least 1.
  2. Default maxBurst to numberOfExecutions when not specified.
  3. Validate burst config before building.

Example fix

// before
var policy = Policy.RateLimit<MyResult>(5, TimeSpan.FromSeconds(10), 0, factory);
// after
var policy = Policy.RateLimit<MyResult>(5, TimeSpan.FromSeconds(10), 5, factory);
Defensive patterns

Strategy: validation

Validate before calling

var maxBurst = config.GetValue("RateLimit:MaxBurst", numberOfExecutions);
if (maxBurst < 1) maxBurst = numberOfExecutions;
var policy = Policy.RateLimit<TResult>(numberOfExecutions, perTimeSpan, maxBurst, retryAfterFactory);

Prevention

When it happens

Trigger: Calling Policy.RateLimit<TResult>(n, perTimeSpan, maxBurst: 0) or a negative maxBurst on the generic sync overload.

Common situations: maxBurst defaulted to 0 from config; burst value omitted in a per-result-type policy.

Related errors


AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13). Data as JSON: /api/errors/c84d05be077f32c7. Report an issue: GitHub.