App-vNext/Polly · error · ArgumentNullException

Value cannot be null.

Error message

Value cannot be null.

What it means

Thrown by CacheAsync<TResult>(IAsyncCacheProvider cacheProvider, TimeSpan ttl, ...) (AsyncCacheTResultSyntax.cs:18) when cacheProvider is null. This is the typed-result convenience overload that wraps the provider via AsyncFor<TResult>() and builds a RelativeTtl; a null provider cannot be typed and would NRE, so it is rejected here.

Source

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

public partial class Policy
{
    /// <summary>
    /// <para>Builds an <see cref="AsyncPolicy{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 AsyncCachePolicy<TResult> CacheAsync<TResult>(IAsyncCacheProvider cacheProvider, TimeSpan ttl, Action<Context, string, Exception>? onCacheError = null)
    {
        if (cacheProvider == null)
        {
            throw new ArgumentNullException(nameof(cacheProvider));
        }

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

    /// <summary>
    /// <para>Builds an <see cref="AsyncPolicy{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 IAsyncCacheProvider, e.g. new MemoryCacheProvider(MemoryCache.Default).
  2. Confirm the DI registration and lifetime of the injected provider.
  3. Construct the provider eagerly before building the policy.

Example fix

// before
var policy = Policy.CacheAsync<MyResult>(null, TimeSpan.FromMinutes(5));

// after
var policy = Policy.CacheAsync<MyResult>(new MemoryCacheProvider(MemoryCache.Default), TimeSpan.FromMinutes(5));
Defensive patterns

Strategy: validation

Validate before calling

ArgumentNullException.ThrowIfNull(cacheProvider);
var policy = Policy.CacheAsync<TResult>(cacheProvider, TimeSpan.FromMinutes(5), onCacheError);

Type guard

static bool IsCacheProviderValid(IAsyncCacheProvider? p) => p is not null;

Prevention

When it happens

Trigger: Calling Policy.CacheAsync<TResult>(null, TimeSpan.FromMinutes(5), onCacheError) — the IAsyncCacheProvider (1st positional) is null.

Common situations: DI did not register the cache provider; passing a field initialized after policy construction; provider creation threw and the variable stayed null.

Related errors


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