dotnet/yarp · error · InvalidOperationException
Error resolving destinations for cluster {cluster.ClusterId}
Error message
Error resolving destinations for cluster {cluster.ClusterId} What it means
When a non-default `IDestinationResolver` is registered (e.g., `DnsDestinationResolver`), YARP resolves destination addresses for each cluster with destinations during config load. If `ResolveDestinationsAsync` throws for a specific cluster, YARP wraps the exception with the cluster ID for identification and rethrows as `InvalidOperationException`. This prevents silently proxying to unresolved destinations.
Source
Thrown at src/ReverseProxy/Management/ProxyConfigManager.cs:382
// Resolve destinations if there are any.
var task = _destinationResolver.ResolveDestinationsAsync(destinations, cancellationToken);
resolverTasks.Add((i, task));
}
}
if (resolverTasks.Count > 0)
{
foreach (var (i, task) in resolverTasks)
{
ResolvedDestinationCollection resolvedDestinations;
try
{
resolvedDestinations = await task;
}
catch (Exception exception)
{
var cluster = clusters[i];
throw new InvalidOperationException($"Error resolving destinations for cluster {cluster.ClusterId}", exception);
}
clusters[i] = clusters[i] with { Destinations = resolvedDestinations.Destinations };
if (resolvedDestinations.ChangeToken is { } token)
{
changeTokens ??= new();
changeTokens.Add(token);
}
}
IChangeToken changeToken;
if (changeTokens is not null)
{
// Combine change tokens from the resolver with the configuration's existing change token.
changeTokens.Add(config.ChangeToken);
changeToken = new CompositeChangeToken(changeTokens);
}
elseView on GitHub (pinned to bd11867bee)
Solutions
- Check the `InnerException` of this `InvalidOperationException` for the resolver-specific error (e.g., `SocketException` for DNS failures).
- Verify all destination hostnames in the cluster config are resolvable from the YARP host — run `nslookup` or `dig` to confirm.
- If using `DnsDestinationResolver`, ensure DNS servers are reachable and the hostnames are registered.
- If using a custom `IDestinationResolver`, add logging and error handling inside it to surface the root cause.
- If a destination is temporarily unresolvable, consider removing it from config until it's available, or add retry logic to the resolver.
- Ensure service discovery infrastructure (Consul, Kubernetes services, etc.) is healthy before starting YARP.
Example fix
// before — cluster references an unresolvable hostname
var clusters = new[]
{
new ClusterConfig
{
ClusterId = "my-cluster",
Destinations = new Dictionary<string, DestinationConfig>
{
["d1"] = new() { Address = "http://nonexistent-host.local:8080" }
}
}
};
// after — use a resolvable hostname or IP
var clusters = new[]
{
new ClusterConfig
{
ClusterId = "my-cluster",
Destinations = new Dictionary<string, DestinationConfig>
{
["d1"] = new() { Address = "http://my-service.default.svc.cluster.local:8080" }
}
}
}; Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-resolve destination hostnames before config load
foreach (var dest in cluster.Destinations?.Values ?? Array.Empty<DestinationConfig>())
{
var host = new Uri(dest.Address).Host;
try { await Dns.GetHostAddressesAsync(host); }
catch { logger.LogWarning("Cannot resolve destination host: {Host}", host); }
} Type guard
// No type guard — destination resolution failures are runtime/DNS conditions.
Try / catch
// This propagates through the InitialLoadAsync wrapper (error 27).
// Catch and inspect at the startup level:
catch (InvalidOperationException ex) when (ex.Message.Contains("Error resolving destinations"))
{
var clusterId = ex.Message; // contains the cluster ID
var rootCause = ex.InnerException; // DNS SocketException, etc.
logger.LogCritical("Destination resolution failed: {Cluster}. Cause: {Cause}", clusterId, rootCause?.Message);
} Prevention
- Verify all destination hostnames are resolvable from the YARP host before deploying.
- If using DnsDestinationResolver, ensure DNS infrastructure is healthy.
- Log the cluster ID and inner exception to quickly identify which destination failed.
When it happens
Trigger: `AddDnsDestinationResolver()` is registered and a cluster has destinations with hostnames that need DNS resolution. `ResolveDestinationsAsync` throws — e.g., DNS lookup fails, a hostname is unresolvable, or a custom resolver implementation encounters an error. The catch at line 379 wraps it with the cluster's ID.
Common situations: A cluster destination is configured with a hostname that doesn't exist in DNS. The DNS server is temporarily unavailable during YARP startup. A custom `IDestinationResolver` implementation throws due to a bug or connectivity issue to its backing store (e.g., a service discovery API is down). A Kubernetes-based deployment references a service that hasn't been created yet.
Related errors
- Configuration Filter Error: Substitution for '{lookup}' in c
- The route config format has changed, routes are now objects
- At least one IProxyConfigProvider is required.
- Unable to load or apply the proxy configuration.
- The proxy config is invalid.
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/c3486ba8fc4a3054.
Report an issue: GitHub.