App-vNext/Polly · error · ObjectDisposedException

The resilience pipeline registry has been disposed and canno

Error message

The resilience pipeline registry has been disposed and cannot be used anymore.

What it means

ResiliencePipelineRegistry sets _disposed on Dispose and every subsequent operation checks EnsureNotDisposed(), throwing ObjectDisposedException. The registry owns pooled/built pipelines and their state, so use after dispose would touch reclaimed resources.

Source

Thrown at src/Polly.Core/Registry/ResiliencePipelineRegistry.cs:268

    {
        if (_genericRegistry.TryGetValue(typeof(TResult), out var genericRegistry))
        {
            return (GenericRegistry<TResult>)genericRegistry;
        }

        return (GenericRegistry<TResult>)_genericRegistry.GetOrAdd(typeof(TResult), new GenericRegistry<TResult>(
            () => new ResiliencePipelineBuilder<TResult>(_activator()),
            _builderComparer,
            _pipelineComparer,
            _builderNameFormatter,
            _instanceNameFormatter));
    }

    private void EnsureNotDisposed()
    {
        if (_disposed)
        {
            throw new ObjectDisposedException("ResiliencePipelineRegistry", "The resilience pipeline registry has been disposed and cannot be used anymore.");
        }
    }
}

View on GitHub (pinned to d0e46bdb1e)

Solutions

  1. Do not dispose the registry while components still resolve pipelines from it; align its lifetime with the longest-lived consumer (usually singleton).
  2. If the registry is scoped/transient by mistake, change it to singleton so it is not disposed per request.
  3. After dispose, create a new registry instance rather than reusing the disposed one.

Example fix

// before
services.AddSingleton<ResiliencePipelineRegistry<string>>();
// a hosted service disposes the provider it was handed...
// ...later
registry.GetPipeline("k"); // ObjectDisposedException

// after
// keep registry as singleton and never dispose from consumers;
// pass IReadOnlyResiliencePipelineRegistry<string> to consumers that should not dispose it.
Defensive patterns

Strategy: try-catch

Try / catch

try { var p = registry.GetPipeline(key); }
catch (ObjectDisposedException) {
    // recreate registry or report shutdown; do not silently continue
}

Prevention

When it happens

Trigger: Calling any method on the registry (GetPipeline, TryAddPipeline, configure callback, etc.) after registry.Dispose() (or its DisposeAsync) has run.

Common situations: DI container disposing the singleton registry while a background service still resolves pipelines from it; sharing one registry across scopes where one scope disposes it; disposing the registry then attempting dynamic reconfiguration.

Related errors


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