App-vNext/Polly · error · ArgumentOutOfRangeException

Value must be equal to or greater than {resolutionOfCircuit.

Error message

Value must be equal to or greater than {resolutionOfCircuit.TotalMilliseconds} milliseconds. This is the minimum resolution of the CircuitBreaker timer.

What it means

Thrown by the async AdvancedCircuitBreaker syntax when samplingDuration is below the 20ms minimum timer resolution. The advanced breaker subdivides the sampling window, so it cannot run below ResolutionOfCircuitTimer (20ms). Fires at construction.

Source

Thrown at src/Polly/CircuitBreaker/AsyncAdvancedCircuitBreakerSyntax.cs:241

        TimeSpan durationOfBreak,
        Action<Exception, CircuitState, TimeSpan, Context> onBreak,
        Action<Context> onReset, Action onHalfOpen)
    {
        var resolutionOfCircuit = TimeSpan.FromTicks(AdvancedCircuitController<EmptyStruct>.ResolutionOfCircuitTimer);

        if (failureThreshold <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(failureThreshold), "Value must be greater than zero.");
        }

        if (failureThreshold > 1)
        {
            throw new ArgumentOutOfRangeException(nameof(failureThreshold), "Value must be less than or equal to one.");
        }

        if (samplingDuration < resolutionOfCircuit)
        {
            throw new ArgumentOutOfRangeException(nameof(samplingDuration), $"Value must be equal to or greater than {resolutionOfCircuit.TotalMilliseconds} milliseconds. This is the minimum resolution of the CircuitBreaker timer.");
        }

        if (minimumThroughput <= 1)
        {
            throw new ArgumentOutOfRangeException(nameof(minimumThroughput), "Value must be greater than one.");
        }

        if (durationOfBreak < TimeSpan.Zero)
        {
            throw new ArgumentOutOfRangeException(nameof(durationOfBreak), "Value must be greater than zero.");
        }

        if (onBreak == null)
        {
            throw new ArgumentNullException(nameof(onBreak));
        }

        if (onReset == null)

View on GitHub (pinned to d0e46bdb1e)

Solutions

  1. Use a samplingDuration >= 20ms; prefer seconds-scale windows for real traffic.
  2. Validate the configured duration against TimeSpan.FromMilliseconds(20) before building.
  3. Double-check config units (seconds vs milliseconds).

Example fix

// before
.AdvancedCircuitBreakerAsync(..., samplingDuration: TimeSpan.Zero, ...)

// after
.AdvancedCircuitBreakerAsync(..., samplingDuration: TimeSpan.FromSeconds(15), ...)
Defensive patterns

Strategy: validation

Validate before calling

if (samplingDuration < TimeSpan.FromMilliseconds(20))
    throw new ArgumentOutOfRangeException(nameof(samplingDuration), "samplingDuration must be >= 20ms.");

Type guard

static bool IsValidSamplingDuration(TimeSpan d) => d >= TimeSpan.FromMilliseconds(20);

Prevention

When it happens

Trigger: Calling AdvancedCircuitBreakerAsync(..., samplingDuration: TimeSpan.FromMilliseconds(1), ...) or TimeSpan.Zero. The check is `samplingDuration < resolutionOfCircuit` (resolutionOfCircuit = 20ms).

Common situations: Supplying TimeSpan.Zero as placeholder, misconfigured units, or a 0/default from config.

Related errors


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