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
- Pass a non-null ISyncCacheProvider that supports For<TResult>().
- Ensure the caching provider package is installed and the provider is constructed/resolved before the call.
- 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
- Ensure the provider supports For<TResult>() (most standard providers do).
- Resolve ISyncCacheProvider from DI so missing registrations fail at startup.
- Assert the provider is non-null in a startup check.
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
- Value cannot be null. (Parameter 'cacheProvider')
- Value cannot be null. (Parameter 'cacheKeyStrategy')
- Value cannot be null. (Parameter 'ttlStrategy')
- Value cannot be null. (Parameter 'onCacheGet')
- Value cannot be null. (Parameter 'onCacheMiss')
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/b171c9912ddf3c47.
Report an issue: GitHub.