{"record":{"id":"f360467c86d39069","repo":"App-vNext/Polly","slug":"invalid-delay-specified","errorCode":null,"errorMessage":"Invalid delay specified.","messagePattern":"Invalid delay specified\\.","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Polly.Core/Utils/CancellationTokenSourcePool.cs","lineNumber":32,"sourceCode":"\n        return new PooledCancellationTokenSourcePool(timeProvider);\n#elif NET6_0_OR_GREATER\n        if (timeProvider == TimeProvider.System)\n        {\n            return PooledCancellationTokenSourcePool.SystemInstance;\n        }\n\n        return new DisposableCancellationTokenSourcePool(timeProvider);\n#else\n        return new DisposableCancellationTokenSourcePool(timeProvider);\n#endif\n    }\n\n    public CancellationTokenSource Get(TimeSpan delay)\n    {\n        if (delay <= TimeSpan.Zero && delay != System.Threading.Timeout.InfiniteTimeSpan)\n        {\n            throw new ArgumentOutOfRangeException(nameof(delay), delay, \"Invalid delay specified.\");\n        }\n\n        return GetCore(delay);\n    }\n\n    protected abstract CancellationTokenSource GetCore(TimeSpan delay);\n\n    public abstract void Return(CancellationTokenSource source);\n\n    protected static bool IsCancellable(TimeSpan delay) => delay != System.Threading.Timeout.InfiniteTimeSpan;\n}\n","sourceCodeStart":14,"sourceCodeEnd":44,"githubUrl":"https://github.com/App-vNext/Polly/blob/d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac/src/Polly.Core/Utils/CancellationTokenSourcePool.cs#L14-L44","documentation":"CancellationTokenSourcePool.Get(TimeSpan delay) rejects any delay that is <= TimeSpan.Zero unless it equals Timeout.InfiniteTimeSpan. The pool underlies timeout/hedging/retry delay scheduling; a non-positive finite delay would create an already-cancelled or invalid token source, so it is rejected up front with ArgumentOutOfRangeException.","triggerScenarios":"Passing TimeSpan.Zero, a negative TimeSpan, or default(TimeSpan) to Get(). InfiniteTimeSpan is the only allowed non-positive value. Normally strategy options validate their delays first; this guards the internal pool entry point.","commonSituations":"A custom strategy or fork that calls the pool directly with an unvalidated delay; misconfigured TimeoutStrategyOptions.Timeout = TimeSpan.Zero or negative; arithmetic that underflows a delay (e.g. maxDelay minus a larger elapsed).","solutions":["Ensure all delay arguments are positive or Timeout.InfiniteTimeSpan before scheduling.","Configure TimeoutStrategyOptions.Timeout / RetryStrategyOptions.BaseDelay to a positive value (or InfiniteTimeSpan to disable).","Guard computed delays: if (delay < TimeSpan.Zero) delay = Timeout.InfiniteTimeSpan; before use."],"exampleFix":"// before\noptions.Timeout = TimeSpan.Zero; // surfaces through the pool\n\n// after\noptions.Timeout = TimeSpan.FromSeconds(30);","handlingStrategy":"validation","validationCode":"static TimeSpan SafeDelay(TimeSpan d) =>\n    d <= TimeSpan.Zero && d != System.Threading.Timeout.InfiniteTimeSpan\n        ? throw new ArgumentOutOfRangeException(nameof(d)) : d;\n// call SafeDelay(delay) before scheduling","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set TimeoutStrategyOptions.Timeout and retry BaseDelay/Delay to positive values (or InfiniteTimeSpan to disable).","Guard computed delays so they never go non-positive except InfiniteTimeSpan.","Validate delays from configuration at startup."],"tags":["timeout","cancellation","pool","argument-out-of-range","polly-core"],"backgroundTag":null,"analyzedSha":"d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac","analyzedAt":"2026-08-13T16:36:01.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}