dotnet/yarp · error · InvalidOperationException

The IReverseProxyFeature Destinations collection was not set

Error message

The IReverseProxyFeature Destinations collection was not set.

What it means

Thrown by ForwarderMiddleware.Invoke when IReverseProxyFeature.AvailableDestinations is null. This is the main proxy forwarding middleware; it expects an upstream pipeline stage (load balancing / destination resolution) to have populated the available destinations. A null value signals the proxy feature was not initialized for the request.

Source

Thrown at src/ReverseProxy/Forwarder/ForwarderMiddleware.cs:43

    {
        ArgumentNullException.ThrowIfNull(next);
        ArgumentNullException.ThrowIfNull(logger);
        ArgumentNullException.ThrowIfNull(forwarder);
        ArgumentNullException.ThrowIfNull(randomFactory);
        _next = next;
        _logger = logger;
        _forwarder = forwarder;
        _randomFactory = randomFactory;
    }

    /// <inheritdoc/>
    public async Task Invoke(HttpContext context)
    {
        ArgumentNullException.ThrowIfNull(context);

        var reverseProxyFeature = context.GetReverseProxyFeature();
        var destinations = reverseProxyFeature.AvailableDestinations
            ?? throw new InvalidOperationException($"The {nameof(IReverseProxyFeature)} Destinations collection was not set.");

        var route = context.GetRouteModel();
        var cluster = route.Cluster!;

        var activity = context.GetYarpActivity();
        activity?.AddTag("proxy.route_id", route.Config.RouteId);
        activity?.AddTag("proxy.cluster_id", cluster.ClusterId);

        if (destinations.Count == 0)
        {
            Log.NoAvailableDestinations(_logger, cluster.ClusterId);
            context.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
            context.Features.Set<IForwarderErrorFeature>(new ForwarderErrorFeature(ForwarderError.NoAvailableDestinations, ex: null));
            activity?.SetStatus(ActivityStatusCode.Error);
            activity?.AddError("Proxy forwarding failed", "No available destinations to forward to");
            return;
        }

View on GitHub (pinned to bd11867bee)

Solutions

  1. Use the standard MapReverseProxy pipeline order: load balancing, then passive health checks, then the forwarder (AddForwarder is included by default).
  2. Do not set AvailableDestinations to null in custom middleware.
  3. Ensure the route matched has a cluster with at least one destination.

Example fix

// before — manual pipeline missing load balancing
app.MapReverseProxy(p => p.UseForwarder());
// after
app.MapReverseProxy(p =>
{
    p.UseLoadBalancing();
    p.UseForwarder();
});
Defensive patterns

Strategy: validation

Validate before calling

var feature = context.GetReverseProxyFeature();
if (feature.AvailableDestinations is null)
{
    context.Response.StatusCode = 503;
    return;
}

Type guard

static bool HasDestinations(HttpContext ctx) =>
    ctx.GetReverseProxyFeature().AvailableDestinations is not null;

Try / catch

try { await _next(context); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Destinations collection was not set"))
{ context.Response.StatusCode = 503; }

Prevention

When it happens

Trigger: The forwarder middleware runs before destinations are set on IReverseProxyFeature, or the feature was not attached. Usually caused by incorrect middleware ordering within MapReverseProxy.

Common situations: Omitting UseLoadBalancing before the forwarder. Custom middleware nulling AvailableDestinations. Pipeline built manually in the wrong order.

Related errors


AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13). Data as JSON: /api/errors/9b4430a8d250e78f. Report an issue: GitHub.