App-vNext/Polly · error · ArgumentNullException

Value cannot be null. (Parameter 'cacheProvider')

Error message

Value cannot be null. (Parameter 'cacheProvider')

What it means

Thrown at policy-construction time by the legacy Polly v7 generic overload CachePolicy<TResult> Cache<TResult>(ISyncCacheProvider, TimeSpan ttl, ...). The provider is the core dependency, so a null value is rejected immediately with ArgumentNullException. The overload then calls cacheProvider.For<TResult>() to obtain a typed provider.

Source

Thrown at src/Polly/Caching/CacheTResultSyntax.cs:22

public partial class Policy
{
    /// <summary>
    /// <para>Builds a <see cref="Policy{TResult}"/> that will function like a result cache for delegate executions returning a <typeparamref name="TResult"/>.</para>
    /// <para>Before executing a delegate, checks whether the <paramref name="cacheProvider"/> holds a value for the cache key specified by <see cref="Context.OperationKey"/>.
    /// If the <paramref name="cacheProvider"/> provides a value from cache, returns that value and does not execute the governed delegate.  If the <paramref name="cacheProvider"/> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider"/>, then returns the value.
    /// </para>
    /// </summary>
    /// <typeparam name="TResult">The type of the result.</typeparam>
    /// <param name="cacheProvider">The cache provider.</param>
    /// <param name="ttl">Duration (ttl) for which to cache values.</param>
    /// <param name="onCacheError">Delegate to call if an exception is thrown when attempting to get a value from or put a value into the cache, passing the execution context, the cache key, and the exception.</param>
    /// <returns>The policy instance.</returns>
    /// <exception cref="ArgumentNullException">Thrown when <paramref name="cacheProvider"/> is <see langword="null"/>.</exception>
    public static CachePolicy<TResult> Cache<TResult>(ISyncCacheProvider cacheProvider, TimeSpan ttl, Action<Context, string, Exception>? onCacheError = null)
    {
        if (cacheProvider == null)
        {
            throw new ArgumentNullException(nameof(cacheProvider));
        }

        return Cache(cacheProvider.For<TResult>(), new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError);
    }

    /// <summary>
    /// <para>Builds a <see cref="Policy{TResult}"/> that will function like a result cache for delegate executions returning a <typeparamref name="TResult"/>.</para>
    /// <para>Before executing a delegate, checks whether the <paramref name="cacheProvider"/> holds a value for the cache key specified by <see cref="Context.OperationKey"/>.
    /// If the <paramref name="cacheProvider"/> provides a value from cache, returns that value and does not execute the governed delegate.  If the <paramref name="cacheProvider"/> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider"/>, then returns the value.
    /// </para>
    /// </summary>
    /// <typeparam name="TResult">The type of the result.</typeparam>
    /// <param name="cacheProvider">The cache provider.</param>
    /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param>
    /// <param name="onCacheError">Delegate to call if an exception is thrown when attempting to get a value from or put a value into the cache, passing the execution context, the cache key, and the exception.</param>
    /// <returns>The policy instance.</returns>
    /// <exception cref="ArgumentNullException">Thrown when <paramref name="cacheProvider"/> is <see langword="null"/>.</exception>
    /// <exception cref="ArgumentNullException">Thrown when <paramref name="ttlStrategy"/> is <see langword="null"/>.</exception>

View on GitHub (pinned to d0e46bdb1e)

Solutions

  1. Pass a non-null ISyncCacheProvider that supports For<TResult>().
  2. Ensure the caching provider package is installed and the provider is constructed/resolved before the call.
  3. If the provider cannot be typed, build one that implements For<TResult> correctly.

Example fix

// before
Policy.Cache<MyResult>(null, TimeSpan.FromMinutes(5));
// after
Policy.Cache<MyResult>(memoryCacheProvider, TimeSpan.FromMinutes(5));
Defensive patterns

Strategy: validation

Validate before calling

if (cacheProvider is null) throw new InvalidOperationException("cacheProvider is not configured.");
var policy = Policy.Cache<TResult>(cacheProvider, ttl);

Type guard

static bool IsCacheProviderValid(Polly.Caching.ISyncCacheProvider? p) => p is not null;

Prevention

When it happens

Trigger: Calling Policy.Cache<TResult>(null, ttl) (or passing a null ISyncCacheProvider) on the typed-result overload.

Common situations: DI did not resolve the ISyncCacheProvider; the backing cache package is missing; you reused a provider variable that was set to null in a refactor.

Related errors


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