App-vNext/Polly · error · ArgumentNullException

Value cannot be null. (Parameter 'onFallback')

Error message

Value cannot be null. (Parameter 'onFallback')

What it means

ArgumentNullException thrown at construction by the non-generic Fallback syntax when onFallback is null. onFallback is the callback invoked before the fallback action runs; the builder requires a non-null delegate (use an empty lambda if you want no side effects).

Source

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

    /// <summary>
    /// Builds a <see cref="FallbackPolicy"/> which provides a fallback action if the main execution fails.  Executes the main delegate, but if this throws a handled exception, first calls <paramref name="onFallback"/> with details of the handled exception and the execution context; then calls <paramref name="fallbackAction"/>.
    /// </summary>
    /// <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 Fallback(this PolicyBuilder policyBuilder, Action<Exception, Context, CancellationToken> fallbackAction, Action<Exception, Context> onFallback)
    {
        if (fallbackAction == null)
        {
            throw new ArgumentNullException(nameof(fallbackAction));
        }

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

        return new FallbackPolicy(
                policyBuilder,
                onFallback,
                fallbackAction);
    }

    private static void EmptyAction(Exception exception)
    {
        // No-op
    }
}

/// <summary>
/// Fluent API for defining a Fallback policy governing executions returning TResult.
/// </summary>
public static class FallbackTResultSyntax

View on GitHub (pinned to d0e46bdb1e)

Solutions

  1. Pass a non-null onFallback delegate, e.g. _ => { } or (_, _) => { }.
  2. If you want the simpler one-argument form, use the overload that supplies a default no-op callback.
  3. Register/resolve the callback correctly from DI so it is never null.

Example fix

// before
var policy = Policy
    .Handle<HttpRequestException>()
    .Fallback((ex, ctx, ct) => { }, onFallback: null);

// after
var policy = Policy
    .Handle<HttpRequestException>()
    .Fallback((ex, ctx, ct) => { }, onFallback: (ex, ctx) => { });
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

static bool IsValid(FallbackPolicy _) => true; // delegates are non-null when constructing via the fluent API

Try / catch

try { var p = builder.Fallback(action, onFallback); } catch (ArgumentNullException ex) when (ex.ParamName == "onFallback") { /* supply no-op */ throw; }

Prevention

When it happens

Trigger: Calling Policy.Handle<...>().Fallback(fallbackAction, onFallback: null), or relying on a params overload where the second positional argument is null.

Common situations: Forgetting the second argument because another overload takes only one; passing null intending 'no callback' rather than an empty delegate; DI resolving the callback as null when the registration was missed.

Related errors


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