{"record":{"id":"01b0f0e00f45957a","repo":"App-vNext/Polly","slug":"the-resilience-pipeline-registry-has-been-disposed","errorCode":null,"errorMessage":"The resilience pipeline registry has been disposed and cannot be used anymore.","messagePattern":"The resilience pipeline registry has been disposed and cannot be used anymore\\.","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"src/Polly.Core/Registry/ResiliencePipelineRegistry.cs","lineNumber":268,"sourceCode":"    {\n        if (_genericRegistry.TryGetValue(typeof(TResult), out var genericRegistry))\n        {\n            return (GenericRegistry<TResult>)genericRegistry;\n        }\n\n        return (GenericRegistry<TResult>)_genericRegistry.GetOrAdd(typeof(TResult), new GenericRegistry<TResult>(\n            () => new ResiliencePipelineBuilder<TResult>(_activator()),\n            _builderComparer,\n            _pipelineComparer,\n            _builderNameFormatter,\n            _instanceNameFormatter));\n    }\n\n    private void EnsureNotDisposed()\n    {\n        if (_disposed)\n        {\n            throw new ObjectDisposedException(\"ResiliencePipelineRegistry\", \"The resilience pipeline registry has been disposed and cannot be used anymore.\");\n        }\n    }\n}\n","sourceCodeStart":250,"sourceCodeEnd":272,"githubUrl":"https://github.com/App-vNext/Polly/blob/d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac/src/Polly.Core/Registry/ResiliencePipelineRegistry.cs#L250-L272","documentation":"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.","triggerScenarios":"Calling any method on the registry (GetPipeline, TryAddPipeline, configure callback, etc.) after registry.Dispose() (or its DisposeAsync) has run.","commonSituations":"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.","solutions":["Do not dispose the registry while components still resolve pipelines from it; align its lifetime with the longest-lived consumer (usually singleton).","If the registry is scoped/transient by mistake, change it to singleton so it is not disposed per request.","After dispose, create a new registry instance rather than reusing the disposed one."],"exampleFix":"// before\nservices.AddSingleton<ResiliencePipelineRegistry<string>>();\n// a hosted service disposes the provider it was handed...\n// ...later\nregistry.GetPipeline(\"k\"); // ObjectDisposedException\n\n// after\n// keep registry as singleton and never dispose from consumers;\n// pass IReadOnlyResiliencePipelineRegistry<string> to consumers that should not dispose it.","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { var p = registry.GetPipeline(key); }\ncatch (ObjectDisposedException) {\n    // recreate registry or report shutdown; do not silently continue\n}","preventionTips":["Register ResiliencePipelineRegistry as a singleton; never dispose it from transient consumers.","Inject IReadOnlyResiliencePipelineRegistry into consumers that must not dispose it.","Order hosted-service shutdown so pipeline consumers stop before the registry disposes."],"tags":["registry","disposed","object-disposed","lifetime","polly-core"],"backgroundTag":null,"analyzedSha":"d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac","analyzedAt":"2026-08-13T16:36:01.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}