App-vNext/Polly · error · ArgumentNullException
Value cannot be null. (Parameter 'cacheKeyStrategy')
Error message
Value cannot be null. (Parameter 'cacheKeyStrategy')
What it means
Thrown by the 8-parameter typed-result overload CacheAsync<TResult>(IAsyncCacheProvider cacheProvider, TimeSpan ttl, ICacheKeyStrategy cacheKeyStrategy, Action onCacheGet, ...) (AsyncCacheTResultSyntax.cs:261) when cacheKeyStrategy is null. The strategy is dereferenced for cacheKeyStrategy.GetCacheKey, so a null instance NREs and is therefore guarded.
Source
Thrown at src/Polly/Caching/AsyncCacheTResultSyntax.cs:278
/// <exception cref="ArgumentNullException">Thrown when <paramref name="onCachePut"/> is <see langword="null"/>.</exception>
public static AsyncCachePolicy<TResult> CacheAsync<TResult>(
IAsyncCacheProvider cacheProvider,
TimeSpan ttl,
ICacheKeyStrategy cacheKeyStrategy,
Action<Context, string> onCacheGet,
Action<Context, string> onCacheMiss,
Action<Context, string> onCachePut,
Action<Context, string, Exception>? onCacheGetError,
Action<Context, string, Exception>? onCachePutError)
{
if (cacheProvider == null)
{
throw new ArgumentNullException(nameof(cacheProvider));
}
if (cacheKeyStrategy is null)
{
throw new ArgumentNullException(nameof(cacheKeyStrategy));
}
return CacheAsync(cacheProvider.AsyncFor<TResult>(), new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError);
}
/// <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 determined by applying the <paramref name="cacheKeyStrategy"/> to the execution <see cref="Context"/>.
/// 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="cacheKeyStrategy">The cache key strategy.</param>
/// <param name="onCacheGet">Delegate to call on a cache hit, when value is returned from cache.</param>
/// <param name="onCacheMiss">Delegate to call on a cache miss.</param>
/// <param name="onCachePut">Delegate to call on cache put.</param>View on GitHub (pinned to d0e46bdb1e)
Solutions
- Pass a non-null ICacheKeyStrategy instance.
- Use DefaultCacheKeyStrategy via an overload that omits the strategy argument if OperationKey suffices.
Example fix
// before Policy.CacheAsync<MyResult>(provider, TimeSpan.FromMinutes(5), (ICacheKeyStrategy)null, onGet, onMiss, onPut, onGetErr, onPutErr); // after Policy.CacheAsync<MyResult>(provider, TimeSpan.FromMinutes(5), new MyKeyStrategy(), onGet, onMiss, onPut, onGetErr, onPutErr);
Defensive patterns
Strategy: validation
Validate before calling
if (cacheKeyStrategy is null) throw new InvalidOperationException("cacheKeyStrategy must be provided.");
var policy = Policy.CacheAsync<TResult>(cacheProvider, TimeSpan.FromMinutes(5), cacheKeyStrategy, onGet, onMiss, onPut, onGetErr, onPutErr); Type guard
static bool IsKeyStrategyValid(ICacheKeyStrategy? s) => s is not null;
Prevention
- Drop the cacheKeyStrategy argument and use the default-key overload when OperationKey suffices.
- Construct the strategy inline at the call site.
- Enable nullable reference types.
When it happens
Trigger: Calling Policy.CacheAsync<TResult>(cacheProvider, TimeSpan.FromMinutes(5), (ICacheKeyStrategy)null, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError).
Common situations: Switching to a custom key strategy but not instantiating it; the strategy DI registration missing.
Related errors
- Value cannot be null.
- Value cannot be null. (Parameter 'cacheProvider')
- onRetry
- sleepDurationProvider
- Value cannot be null. (Parameter 'ttlStrategy')
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/588f6767f5ffd59f.
Report an issue: GitHub.