App-vNext/Polly · error · ObjectDisposedException
This resilience pipeline has been disposed and cannot be use
Error message
This resilience pipeline has been disposed and cannot be used anymore.
What it means
ResiliencePipeline wraps its component in a ComponentDisposeHelper that tracks a _disposed flag; EnsureNotDisposed throws ObjectDisposedException once disposed. Every execution first calls EnsureNotDisposed, so using a pipeline after DisposeAsync/Dispose reclaims its underlying strategies is blocked.
Source
Thrown at src/Polly.Core/Utils/Pipeline/ComponentDisposeHelper.cs:33
public ValueTask DisposeAsync()
{
if (EnsureDisposable())
{
return ForceDisposeAsync();
}
return default;
}
public void EnsureNotDisposed()
{
if (_disposed)
{
ThrowDisposed();
}
}
private static void ThrowDisposed() => throw new ObjectDisposedException("ResiliencePipeline", "This resilience pipeline has been disposed and cannot be used anymore.");
public ValueTask ForceDisposeAsync()
{
_disposed = true;
return _component.DisposeAsync();
}
private bool EnsureDisposable()
{
if (_disposeBehavior == DisposeBehavior.Ignore)
{
return false;
}
if (_disposeBehavior == DisposeBehavior.Reject)
{
throw new InvalidOperationException("Disposing this resilience pipeline is not allowed because it is owned by the pipeline registry.");
}View on GitHub (pinned to d0e46bdb1e)
Solutions
- Do not dispose the pipeline until all in-flight and future executions have completed; track its lifetime explicitly.
- If using 'using'/await using, ensure the scope encloses all usage including awaited continuations.
- For registry-managed pipelines, do not dispose the pipeline yourself; let the registry own it.
Example fix
// before
await using var pipeline = builder.Build();
// ... pipeline goes out of scope ...
await pipeline.ExecuteAsync(work); // ObjectDisposedException
// after
var pipeline = builder.Build();
try { await pipeline.ExecuteAsync(work); }
finally { await pipeline.DisposeAsync(); } Defensive patterns
Strategy: try-catch
Try / catch
try { await pipeline.ExecuteAsync(work); }
catch (ObjectDisposedException) {
// obtain a fresh pipeline or report shutdown
} Prevention
- Do not dispose a pipeline while in-flight or future executions may still use it.
- Ensure 'await using'/'using' scopes enclose all usage including awaited continuations.
- For shared pipelines, manage lifetime centrally rather than per-consumer.
When it happens
Trigger: Calling pipeline.Execute(...)/ExecuteAsync(...) after the pipeline has been disposed. This includes pipelines you explicitly disposed and those whose DisposeBehavior allowed disposal.
Common situations: Disposing a pipeline held in a field while a concurrent request still uses it; using a 'using var pipeline' that disposes before an async continuation resumes; disposing a registry-owned pipeline reference after the registry disposed it.
Related errors
- The resilience pipeline registry has been disposed and canno
- Disposing this resilience pipeline is not allowed because it
- This instance of 'CircuitBreakerStateProvider' is already in
- TaskExecution is not initialized.
- Unable to accept outcome for a task that is not completed.
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/6a0bf104e6f9358d.
Report an issue: GitHub.