dotnet/yarp · error · ArgumentException
TConsumer must implement at least one IMetricsConsumer inter
Error message
TConsumer must implement at least one IMetricsConsumer interface.
What it means
The generic AddMetricsConsumer<TConsumer>() uses IsAssignableFrom to detect each closed IMetricsConsumer<TMetrics> interface on TConsumer and register a forwarding factory. With no generic constraint, a TConsumer that implements none triggers ArgumentException(paramName: TConsumer) at startup.
Source
Thrown at src/TelemetryConsumption/TelemetryConsumptionExtensions.cs:248
services.AddSingleton(services => (IMetricsConsumer<NameResolutionMetrics>)services.GetRequiredService<TConsumer>());
implementsAny = true;
}
if (typeof(IMetricsConsumer<NetSecurityMetrics>).IsAssignableFrom(typeof(TConsumer)))
{
services.AddSingleton(services => (IMetricsConsumer<NetSecurityMetrics>)services.GetRequiredService<TConsumer>());
implementsAny = true;
}
if (typeof(IMetricsConsumer<SocketsMetrics>).IsAssignableFrom(typeof(TConsumer)))
{
services.AddSingleton(services => (IMetricsConsumer<SocketsMetrics>)services.GetRequiredService<TConsumer>());
implementsAny = true;
}
if (!implementsAny)
{
throw new ArgumentException("TConsumer must implement at least one IMetricsConsumer interface.", nameof(TConsumer));
}
services.TryAddSingleton<TConsumer>();
services.AddTelemetryListeners();
return services;
}
}
View on GitHub (pinned to bd11867bee)
Solutions
- Implement at least one IMetricsConsumer<TMetrics> interface on TConsumer.
- If the type handles telemetry events, switch to AddTelemetryConsumer<TConsumer>().
- Add a compile-time `where TConsumer : IMetricsConsumer<HttpClientMetrics>` constraint on a wrapper to force a build error instead.
Example fix
// before
public class MyConsumer { ... }
services.AddMetricsConsumer<MyConsumer>();
// after
public class MyConsumer : IMetricsConsumer<SocketsMetrics> { ... }
services.AddMetricsConsumer<MyConsumer>(); Defensive patterns
Strategy: type-guard
Validate before calling
static bool ImplementsAnyMetricsConsumer<T>() =>
typeof(IMetricsConsumer<HttpClientMetrics>).IsAssignableFrom(typeof(T))
|| typeof(IMetricsConsumer<SocketsMetrics>).IsAssignableFrom(typeof(T))
|| typeof(IMetricsConsumer<NetSecurityMetrics>).IsAssignableFrom(typeof(T));
if (ImplementsAnyMetricsConsumer<MyConsumer>())
services.AddMetricsConsumer<MyConsumer>(); Type guard
public static IServiceCollection AddMyMetricsConsumer<TConsumer>(this IServiceCollection services)
where TConsumer : class, IMetricsConsumer<HttpClientMetrics>
=> services.AddMetricsConsumer<TConsumer>(); Prevention
- Add a generic constraint on your wrapper extension to force a build-time error.
- Verify the closed IMetricsConsumer<> generic argument matches a type YARP actually emits.
- Unit-test that each metrics consumer implements the expected interface.
When it happens
Trigger: Calling services.AddMetricsConsumer<MyClass>() where MyClass implements no IMetricsConsumer<...> interface.
Common situations: Forgetting the interface on the consumer; version change that renamed/removed a metrics type so IsAssignableFrom no longer matches; passing a telemetry-only type to the metrics generic overload.
Related errors
- TConsumer must implement at least one I*TelemetryConsumer in
- The consumer must implement at least one IMetricsConsumer in
- The consumer must implement at least one I*TelemetryConsumer
- A consumer may not be null
- The transform contains more parameters than expected: {strin
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/d172b1cf60930d1e.
Report an issue: GitHub.