App-vNext/Polly · error · ArgumentNullException

Value cannot be null. (Parameter 'fallbackAction')

Error message

Value cannot be null. (Parameter 'fallbackAction')

What it means

ArgumentNullException thrown by Fallback<TResult>(PolicyBuilder<TResult>, Func<TResult> fallbackAction, Action<DelegateResult<TResult>> onFallback) when fallbackAction is null. The fallback value producer is required; without it the policy cannot supply a substitute result.

Source

Thrown at src/Polly/Fallback/FallbackSyntax.cs:218

        return policyBuilder.Fallback((_, _, _) => fallbackValue, (outcome, _) => onFallback(outcome));
    }

    /// <summary>
    /// Builds a <see cref="FallbackPolicy"/> which provides a fallback value if the main execution fails.  Executes the main delegate, but if this throws a handled exception or raises a handled result, first calls <paramref name="onFallback"/> with details of the handled exception or result; then calls <paramref name="fallbackAction"/> and returns its result.
    /// </summary>
    /// <typeparam name="TResult">The type of the result.</typeparam>
    /// <param name="policyBuilder">The policy builder.</param>
    /// <param name="fallbackAction">The fallback action.</param>
    /// <param name="onFallback">The action to call before invoking the fallback delegate.</param>
    /// <exception cref="ArgumentNullException">Thrown when <paramref name="fallbackAction"/> is <see langword="null"/>.</exception>
    /// <exception cref="ArgumentNullException">Thrown when <paramref name="onFallback"/> is <see langword="null"/>.</exception>
    /// <returns>The policy instance.</returns>
    public static FallbackPolicy<TResult> Fallback<TResult>(this PolicyBuilder<TResult> policyBuilder, Func<TResult> fallbackAction, Action<DelegateResult<TResult>> onFallback)
    {
        if (fallbackAction == null)
        {
            throw new ArgumentNullException(nameof(fallbackAction));
        }

        if (onFallback == null)
        {
            throw new ArgumentNullException(nameof(onFallback));
        }

        return policyBuilder.Fallback((_, _, _) => fallbackAction(), (outcome, _) => onFallback(outcome));
    }

    /// <summary>
    /// Builds a <see cref="FallbackPolicy"/> which provides a fallback value if the main execution fails.  Executes the main delegate, but if this throws a handled exception or raises a handled result, first calls <paramref name="onFallback"/> with details of the handled exception or result; then calls <paramref name="fallbackAction"/> and returns its result.
    /// </summary>
    /// <typeparam name="TResult">The type of the result.</typeparam>
    /// <param name="policyBuilder">The policy builder.</param>
    /// <param name="fallbackAction">The fallback action.</param>
    /// <param name="onFallback">The action to call before invoking the fallback delegate.</param>
    /// <exception cref="ArgumentNullException">Thrown when <paramref name="fallbackAction"/> is <see langword="null"/>.</exception>

View on GitHub (pinned to d0e46bdb1e)

Solutions

  1. Supply a non-null Func<TResult>.
  2. Validate the DI registration for the fallback factory before building the policy.
  3. Default to a value-returning lambda: () => default if a real producer is unavailable.

Example fix

// before
var policy = Policy<int>
    .Handle<HttpRequestException>()
    .Fallback(fallbackAction: null, onFallback: _ => { });

// after
var policy = Policy<int>
    .Handle<HttpRequestException>()
    .Fallback(fallbackAction: () => cache.GetCached(), onFallback: _ => { });
Defensive patterns

Strategy: validation

Validate before calling

if (fallbackAction is null) throw new ArgumentNullException(nameof(fallbackAction));
var policy = Policy<TResult>.Handle<X>().Fallback(fallbackAction, onFallback);

Type guard

static Func<T> EnsureProducer<T>(Func<T> p) => p ?? (() => default);

Try / catch

try { var p = builder.Fallback(fallbackAction, onFallback); } catch (ArgumentNullException ex) when (ex.ParamName == "fallbackAction") { /* register producer */ throw; }

Prevention

When it happens

Trigger: Calling Policy<TResult>.Handle<...>().Fallback(fallbackAction: null, onFallback).

Common situations: Injecting the fallback factory from DI where the registration is missing; conditional initialization that left the field null.

Related errors


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