{"record":{"id":"20999833ed17d66b","repo":"dotnet/yarp","slug":"unable-to-load-or-apply-the-proxy-configuration","errorCode":null,"errorMessage":"Unable to load or apply the proxy configuration.","messagePattern":"Unable to load or apply the proxy configuration\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/ReverseProxy/Management/ProxyConfigManager.cs","lineNumber":212,"sourceCode":"            var proxyConfigs = ExtractListOfProxyConfigs(_configs);\n\n            foreach (var configChangeListener in _configChangeListeners)\n            {\n                configChangeListener.ConfigurationLoaded(proxyConfigs);\n            }\n\n            await ApplyConfigAsync(routes, clusters);\n\n            foreach (var configChangeListener in _configChangeListeners)\n            {\n                configChangeListener.ConfigurationApplied(proxyConfigs);\n            }\n\n            ListenForConfigChanges();\n        }\n        catch (Exception ex)\n        {\n            throw new InvalidOperationException(\"Unable to load or apply the proxy configuration.\", ex);\n        }\n\n        // Initial active health check is run in the background.\n        // Directly enumerate the ConcurrentDictionary to limit locking and copying.\n        _ = _activeHealthCheckMonitor.CheckHealthAsync(_clusters.Select(pair => pair.Value));\n        return this;\n    }\n\n    private async Task ReloadConfigAsync()\n    {\n        _configChangeSource.Dispose();\n\n        var sourcesChanged = false;\n        var routes = new List<RouteConfig>();\n        var clusters = new List<ClusterConfig>();\n        var reloadedConfigs = new List<(ConfigState Config, ValueTask<IProxyConfig> ResolveTask)>();\n\n        // Start reloading changed configurations.","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/ReverseProxy/Management/ProxyConfigManager.cs#L194-L230","documentation":"This is a wrapper exception thrown by the initial config-loading try-catch in `ProxyConfigManager.InitialLoadAsync`. Any exception during provider enumeration, config validation, route/cluster verification, destination resolution, or change-token wiring is caught and re-wrapped as `InvalidOperationException` with this message and the original exception as `InnerException`. The intent is to make startup config failures fatal and clearly attributed.","triggerScenarios":"Any exception in the `InitialLoadAsync` try block (lines 171-208): a provider's `GetConfig()` throws, a config property is null, route/cluster validation fails, destination resolution fails, or `ApplyConfigAsync` throws. The outer catch at line 210 wraps it. The real cause is in `ex.InnerException` (and potentially `ex.InnerException.InnerException` for AggregateException from validation).","commonSituations":"The appsettings.json `ReverseProxy` section has malformed configuration (invalid route patterns, missing cluster IDs, duplicate routes, invalid header match rules). A custom config provider throws during initialization. Destination resolution (e.g., DNS) fails for a configured cluster. This is the most common startup failure in YARP.","solutions":["Inspect `ex.InnerException` (and `InnerException.InnerException` for AggregateException) to find the root cause — the wrapper message alone is not actionable.","If the inner exception is an `AggregateException` with validation errors, enumerate `innerException.InnerExceptions` to see each route/cluster validation failure individually.","Use `IConfigValidator` diagnostics or the validation errors collection to identify the specific config field that is wrong.","Validate your configuration file against the expected schema before deploying (route patterns, cluster IDs, header matcher modes, transform definitions).","If using a custom config provider, add logging inside its `GetConfig()` to diagnose what data it produces."],"exampleFix":"// To diagnose the real error, unwrap the chain at startup\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Unable to load or apply\"))\n{\n    var inner = ex.InnerException;\n    if (inner is AggregateException agg)\n    {\n        foreach (var validationError in agg.InnerExceptions)\n            Console.Error.WriteLine($\"Config error: {validationError.Message}\");\n    }\n    else\n    {\n        Console.Error.WriteLine($\"Config load failed: {inner?.Message}\");\n    }\n    throw;\n}","handlingStrategy":"try-catch","validationCode":"// Pre-validate config before app starts\n// Use IConfigValidator implementations to check config during a dry-run\nvar sp = builder.Services.BuildServiceProvider();\nvar configManager = sp.GetRequiredService<ProxyConfigManager>();\ntry { await configManager.InitialLoadAsync(); }\ncatch (InvalidOperationException ex) { /* log inner exceptions */ }","typeGuard":"// No type guard — this is a config-content validation issue.","tryCatchPattern":"try { await app.Services.GetRequiredService<ProxyConfigManager>().InitialLoadAsync(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Unable to load or apply\"))\n{\n    var inner = ex.InnerException;\n    if (inner is AggregateException agg)\n        foreach (var e in agg.InnerExceptions) Console.Error.WriteLine(e.Message);\n    else\n        Console.Error.WriteLine(inner?.Message ?? ex.Message);\n    throw;\n}","preventionTips":["Always inspect `InnerException` (and `InnerExceptions` for AggregateException) — the wrapper message is generic.","Run a config validation dry-run in CI before deploying.","Log the full exception chain during startup to catch config errors early."],"tags":["configuration","startup","wrapper-exception","validation","config-provider"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}