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
- Enumerate `aggregateException.InnerExceptions` to see every individual validation error with its specific message.
- 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.
- If using `appsettings.json`, validate the `ReverseProxy:Routes` and `ReverseProxy:Clusters` sections against the schema and YARP documentation.
- For custom validators, ensure the validation logic matches your config expectations and the error messages are descriptive.
- 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
- Always enumerate the AggregateException.InnerExceptions to see every validation error at once.
- Add a config-validation step in CI that loads and validates the config before deploying.
- Keep route IDs unique and ensure every route's ClusterId references an existing cluster.
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
- Unable to load or apply the proxy configuration.
- Configuration Filter Error: Substitution for '{lookup}' in c
- A non-empty CustomTransform value is required
- A non-empty CustomMetadata value is required
- The route config format has changed, routes are now objects
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/ccd6561875bd7c82.
Report an issue: GitHub.