dotnet/yarp · critical · AggregateException

The proxy config is invalid.

Error message

The proxy config is invalid.

What it means

After loading all config, `ApplyConfigAsync` runs `VerifyClustersAsync` and `VerifyRoutesAsync` which use registered `IConfigValidator` instances to check every cluster and route. If any validation errors are collected, they are aggregated into a single `AggregateException` with this message. Each inner exception describes a specific validation failure (duplicate route IDs, invalid patterns, missing cluster references, etc.).

Source

Thrown at src/ReverseProxy/Management/ProxyConfigManager.cs:490

            catch (ObjectDisposedException) { }
        }

        static void ReloadConfig(object? state)
        {
            var manager = (ProxyConfigManager)state!;
            _ = manager.ReloadConfigAsync();
        }
    }

    // Throws for validation failures
    private async Task<bool> ApplyConfigAsync(IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters)
    {
        var (configuredClusters, clusterErrors) = await VerifyClustersAsync(clusters, cancellation: default);
        var (configuredRoutes, routeErrors) = await VerifyRoutesAsync(routes, configuredClusters, cancellation: default);

        if (routeErrors.Count > 0 || clusterErrors.Count > 0)
        {
            throw new AggregateException("The proxy config is invalid.", routeErrors.Concat(clusterErrors));
        }

        // Update clusters first because routes need to reference them.
        UpdateRuntimeClusters(configuredClusters);
        var routesChanged = UpdateRuntimeRoutes(configuredRoutes);
        return routesChanged;
    }

    private async Task<(IList<RouteConfig>, IList<Exception>)> VerifyRoutesAsync(IReadOnlyList<RouteConfig> routes, IReadOnlyDictionary<string, ClusterConfig> clusters, CancellationToken cancellation)
    {
        if (routes is null)
        {
            return (Array.Empty<RouteConfig>(), Array.Empty<Exception>());
        }

        var seenRouteIds = new HashSet<string>(routes.Count, StringComparer.OrdinalIgnoreCase);
        var configuredRoutes = new List<RouteConfig>(routes.Count);
        var errors = new List<Exception>();

View on GitHub (pinned to bd11867bee)

Solutions

  1. Enumerate `aggregateException.InnerExceptions` to see every individual validation error with its specific message.
  2. Fix each validation error in the configuration source (appsettings.json, in-memory config, or custom provider) — start with the first error as later errors may be cascading.
  3. If using `appsettings.json`, validate the `ReverseProxy:Routes` and `ReverseProxy:Clusters` sections against the schema and YARP documentation.
  4. For custom validators, ensure the validation logic matches your config expectations and the error messages are descriptive.
  5. Use YARP's config validation at startup (it happens automatically) and fix all reported errors before deploying.

Example fix

// Inspect the aggregate to find all validation errors
try
{
    builder.Services.AddReverseProxy().LoadFromConfig(config);
    // ... app startup ...
}
catch (InvalidOperationException ex) when (ex.InnerException is AggregateException agg)
{
    foreach (var error in agg.InnerExceptions)
    {
        Console.Error.WriteLine($"Validation error: {error.Message}");
    }
    // Fix each reported error in appsettings.json or config source
    throw;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate routes and clusters before app startup
// Manually run validators or parse config in a test:
var configText = File.ReadAllText("appsettings.json");
var config = JsonSerializer.Deserialize<JsonElement>(configText);
// Check for duplicate route IDs, missing cluster references, etc.

Type guard

// No type guard — config validation failures are content errors, not type errors.

Try / catch

try { builder.Services.AddReverseProxy().LoadFromConfig(config); }
catch (InvalidOperationException ex) when (ex.InnerException is AggregateException agg)
{
    foreach (var e in agg.InnerExceptions)
        Console.Error.WriteLine($"Validation: {e.Message}");
    throw;
}

Prevention

When it happens

Trigger: Any registered `IConfigValidator` (built-in or custom) adds an exception to the errors list during validation. Common built-in validators check: route pattern validity, cluster ID references, transform validity, header matcher correctness, load-balancing policy names, and health check configuration. The error count being > 0 at line 488 triggers the AggregateException.

Common situations: A route references a `ClusterId` that doesn't exist in the clusters list. Two routes share the same `RouteId`. A route pattern is malformed. A transform is misconfigured (unknown transform name, missing required parameter). A cluster has an invalid load-balancing policy or health check endpoint configuration. Header match config has invalid mode/value combinations.

Related errors


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