dotnet/yarp · error · InvalidOperationException

The IReverseProxyFeature Cluster was not set.

Error message

The IReverseProxyFeature Cluster was not set.

What it means

Thrown by HttpSysDelegatorMiddleware.Invoke when IReverseProxyFeature.Cluster is null. The middleware needs the matched cluster to read config (e.g., ClusterId) and to proceed with delegation. A null cluster means the proxy feature was not fully initialized, usually because the route had no resolvable cluster.

Source

Thrown at src/ReverseProxy/Delegation/HttpSysDelegatorMiddleware.cs:45

        ArgumentNullException.ThrowIfNull(next);
        ArgumentNullException.ThrowIfNull(logger);
        ArgumentNullException.ThrowIfNull(delegator);
        ArgumentNullException.ThrowIfNull(randomFactory);
        _next = next;
        _logger = logger;
        _delegator = delegator;
        _randomFactory = randomFactory;
    }

    public 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 cluster = reverseProxyFeature.Cluster
            ?? throw new InvalidOperationException($"The {nameof(IReverseProxyFeature)} Cluster was not set.");

        if (destinations.Any())
        {
            // This logic mimics behavior in ForwarderMiddleware, except we save the chosen destination back
            // to the proxy feature to ensure a delegation destination doesn't slip past this middleware.
            var destination = destinations[0];
            if (destinations.Count > 1)
            {
                var random = _randomFactory.CreateRandomInstance();
                Log.MultipleDestinationsAvailable(_logger, reverseProxyFeature.Cluster.Config.ClusterId);
                destination = destinations[random.Next(destinations.Count)];
                reverseProxyFeature.AvailableDestinations = destination;
            }

            if (destination.ShouldUseHttpSysDelegation())
            {
                reverseProxyFeature.ProxiedDestination = destination;

View on GitHub (pinned to bd11867bee)

Solutions

  1. Verify every route's ClusterId matches a defined cluster in the configuration.
  2. Ensure the proxy feature-population middleware runs before UseHttpSysDelegation.
  3. Validate config at startup (config validation is enabled by default) to catch dangling ClusterId references.

Example fix

// before — appsettings.json
"Routes": { "r1": { "ClusterId": "clusterX", ... } }
// Clusters has no "clusterX"
// after
"Clusters": { "clusterX": { "Destinations": { ... } } }
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

static bool HasCluster(HttpContext ctx) =>
    ctx.GetReverseProxyFeature().Cluster is not null;

Try / catch

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

Prevention

When it happens

Trigger: The matched route's ClusterId does not correspond to any configured cluster, or the proxy feature population stage did not run. The middleware reads reverseProxyFeature.Cluster and finds it null.

Common situations: Route references a ClusterId that is misspelled or missing from the Clusters config. Cluster was removed by a config reload while a request was in flight. Custom middleware interfered with feature population.

Related errors


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