App-vNext/Polly · error · KeyNotFoundException

Unable to find a generic resilience pipeline of '{typeof(TRe

Error message

Unable to find a generic resilience pipeline of '{typeof(TResult).Name}' associated with the key '{key}'. Please ensure that either the generic resilience pipeline or the generic builder is registered.

What it means

The generic GetPipeline<TResult>(key) throws KeyNotFoundException when no generic pipeline or generic builder for that exact TResult was registered under the key. Generic and non-generic pipelines live in separate namespaces per key, so a non-generic registration will not satisfy a generic lookup.

Source

Thrown at src/Polly.Core/Registry/ResiliencePipelineProvider.cs:43

        throw new KeyNotFoundException($"Unable to find a resilience pipeline associated with the key '{key}'. " +
            $"Please ensure that either the resilience pipeline or the builder is registered.");
    }

    /// <summary>
    /// Retrieves a generic resilience pipeline from the provider using the specified key.
    /// </summary>
    /// <typeparam name="TResult">The type of result that the resilience pipeline handles.</typeparam>
    /// <param name="key">The key used to identify the resilience pipeline.</param>
    /// <returns>The resilience pipeline associated with the specified key.</returns>
    /// <exception cref="KeyNotFoundException">Thrown when no resilience pipeline is found for the specified key.</exception>
    public virtual ResiliencePipeline<TResult> GetPipeline<TResult>(TKey key)
    {
        if (TryGetPipeline<TResult>(key, out var pipeline))
        {
            return pipeline;
        }

        throw new KeyNotFoundException($"Unable to find a generic resilience pipeline of '{typeof(TResult).Name}' associated with the key '{key}'. " +
            $"Please ensure that either the generic resilience pipeline or the generic builder is registered.");
    }

    /// <summary>
    /// Tries to get a resilience pipeline from the provider using the specified key.
    /// </summary>
    /// <param name="key">The key used to identify the resilience pipeline.</param>
    /// <param name="pipeline">The output resilience pipeline if found, <see langword="null"/> otherwise.</param>
    /// <returns><see langword="true"/> if the pipeline was found, <see langword="false"/> otherwise.</returns>
    public abstract bool TryGetPipeline(TKey key, [NotNullWhen(true)] out ResiliencePipeline? pipeline);

    /// <summary>
    /// Tries to get a generic resilience pipeline from the provider using the specified key.
    /// </summary>
    /// <typeparam name="TResult">The type of result that the resilience pipeline handles.</typeparam>
    /// <param name="key">The key used to identify the resilience pipeline.</param>
    /// <param name="pipeline">The output resilience pipeline if found, <see langword="null"/> otherwise.</param>
    /// <returns><see langword="true"/> if the pipeline was found, <see langword="false"/> otherwise.</returns>

View on GitHub (pinned to d0e46bdb1e)

Solutions

  1. Register a generic builder/pipeline for the exact TResult: registry.TryAddPipeline<TResult>(key, ...) or TryAddBuilder<TResult>(...).
  2. If the pipeline is genuinely type-agnostic, resolve the non-generic GetPipeline(key) and wrap with .AsPipeline<TResult>() explicitly.
  3. Confirm the TResult used at resolution matches the one used at registration, including namespace.

Example fix

// before
registry.TryAddPipeline("api", b => b.AddRetry(new()));
var p = provider.GetPipeline<HttpResponseMessage>("api"); // throws

// after
registry.TryAddPipeline<HttpResponseMessage>("api", b => b.AddRetry(new RetryStrategyOptions<HttpResponseMessage>()));
var p = provider.GetPipeline<HttpResponseMessage>("api");
Defensive patterns

Strategy: validation

Validate before calling

if (provider.TryGetPipeline<TResult>(key, out var pipeline)) {
    // use pipeline
} else {
    // register the generic pipeline/builder for TResult, or fall back
}

Try / catch

try { var p = provider.GetPipeline<TResult>(key); }
catch (KeyNotFoundException ex) when (ex.Message.Contains(typeof(TResult).Name)) {
    // register generic builder for TResult or use non-generic pipeline
}

Prevention

When it happens

Trigger: Calling provider.GetPipeline<string>(key) when only a non-generic pipeline was registered under key, or when only a different TResult was registered. Also when the generic builder was never added.

Common situations: Registering a builder as non-generic but resolving as generic; TResult mismatch (e.g. registered HttpResponseMessage but resolving as object); assuming generic resolution falls back to non-generic.

Related errors


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