dotnet/yarp · error · ArgumentException
No {typeof(T)} was found for the id '{lookup}'.
Error message
No {typeof(T)} was found for the id '{lookup}'. What it means
Thrown by ServiceLookupHelper.GetRequiredServiceById when a configured policy id cannot be found in the frozen name->policy dictionary. The lookup first substitutes defaultId when the supplied id is null or empty, then does a case-insensitive TryGetValue; on miss it throws ArgumentException(paramName: id). It is reached from request-time middleware (LoadBalancingMiddleware, SessionAffinityMiddleware, PassiveHealthCheckMiddleware) and the active health check monitor when they resolve the policy named in the cluster/route config.
Source
Thrown at src/ReverseProxy/Utilities/ServiceLookupHelper.cs:39
{
throw new ArgumentException($"More than one {typeof(T)} found with the same identifier.", nameof(services));
}
}
return result.ToFrozenDictionary(StringComparer.OrdinalIgnoreCase);
}
public static T GetRequiredServiceById<T>(this FrozenDictionary<string, T> services, string? id, string defaultId)
{
var lookup = id;
if (string.IsNullOrEmpty(lookup))
{
lookup = defaultId;
}
if (!services.TryGetValue(lookup, out var result))
{
throw new ArgumentException($"No {typeof(T)} was found for the id '{lookup}'.", nameof(id));
}
return result;
}
}
View on GitHub (pinned to bd11867bee)
Solutions
- Register the missing policy via the appropriate Add* extension (AddActiveHealthCheckPolicy, AddPassiveHealthCheckPolicy, AddLoadBalancingPolicies, AddSessionAffinityPolicies, etc.).
- Correct the policy name in the cluster/route config to exactly match a registered policy's Name.
- Omit the policy setting (or set it to null/empty) to fall back to the documented defaultId for that category.
- Use the matching config validator (LoadBalancingValidator, HealthCheckValidator, SessionAffinityValidator) which reports the missing policy as a validation error before request time.
Example fix
// before "LoadBalancingPolicy": "LeastRequests" // not registered // after builder.Services.AddLoadBalancingPolicies(); // and/or use a registered name: "LoadBalancingPolicy": "PowerOfTwoChoices"
Defensive patterns
Strategy: validation
Validate before calling
// Validate every referenced policy name is registered before serving traffic.
var registered = builder.Services.BuildServiceProvider()
.GetServices<ILoadBalancingPolicy>().Select(p => p.Name)
.ToHashSet(StringComparer.OrdinalIgnoreCase);
foreach (var cluster in config.Clusters) {
var name = cluster.LoadBalancingPolicy;
if (!string.IsNullOrEmpty(name) && !registered.Contains(name))
Console.Error.WriteLine($"Unknown LoadBalancingPolicy '{name}' on cluster {cluster.ClusterId}");
} Try / catch
// Last-resort request-time guard around the resolving middleware.
try { /* GetRequiredServiceById call */ }
catch (ArgumentException ex) when (ex.Message.Contains("was found for the id")) {
context.Response.StatusCode = 502;
await context.Response.WriteAsync("Upstream policy misconfigured");
} Prevention
- Rely on YARP's config validators (LoadBalancingValidator, HealthCheckValidator, SessionAffinityValidator) which surface missing policies as validation errors at startup.
- Keep policy names in constants and reference the same constant from config and registration.
- Add an integration test that loads your config against the real DI container to catch unregistered names.
- When you remove or rename a policy registration, grep config files for the old name.
When it happens
Trigger: A cluster config sets LoadBalancingPolicy, HealthCheck.Active/Passive policy, SessionAffinity.Policy/FailurePolicy, or an AvailableDestinations policy to a name that no registered policy exposes. For example Cluster.LoadBalancingPolicy = "LeastRequests" while only the default policies are registered, or referencing a custom session affinity policy whose Add* registration was never called.
Common situations: Typo in the config policy name; referencing a policy that lives in a package/extension not yet added to DI; enabling a policy in config before registering it (e.g. setting HealthCheck.Active.Policy without calling AddActiveHealthCheckPolicy); case-only differences are tolerated but trailing spaces or alternate spellings are not; migrating a policy name after a YARP version rename without updating config.
Related errors
- Failed to resolve host '{hostName}'. See {nameof(Exception.I
- More than one {typeof(T)} found with the same identifier.
- A non-empty CustomMetadata value is required
- Configuration Filter Error: Substitution for '{lookup}' in c
- A non-empty CustomTransform value is required
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/2abee8d8e089a84a.
Report an issue: GitHub.