dotnet/yarp · error · ArgumentException

TConsumer must implement at least one I*TelemetryConsumer in

Error message

TConsumer must implement at least one I*TelemetryConsumer interface.

What it means

The generic AddTelemetryConsumer<TConsumer>() probes typeof(TConsumer) with IsAssignableFrom for each I*TelemetryConsumer interface and registers a forwarding factory for each match. Because there is no generic constraint enforcing the interface, the check is performed at runtime; if TConsumer implements none, it throws ArgumentException(paramName: TConsumer).

Source

Thrown at src/TelemetryConsumption/TelemetryConsumptionExtensions.cs:139

            services.AddSingleton(services => (INameResolutionTelemetryConsumer)services.GetRequiredService<TConsumer>());
            implementsAny = true;
        }

        if (typeof(INetSecurityTelemetryConsumer).IsAssignableFrom(typeof(TConsumer)))
        {
            services.AddSingleton(services => (INetSecurityTelemetryConsumer)services.GetRequiredService<TConsumer>());
            implementsAny = true;
        }

        if (typeof(ISocketsTelemetryConsumer).IsAssignableFrom(typeof(TConsumer)))
        {
            services.AddSingleton(services => (ISocketsTelemetryConsumer)services.GetRequiredService<TConsumer>());
            implementsAny = true;
        }

        if (!implementsAny)
        {
            throw new ArgumentException("TConsumer must implement at least one I*TelemetryConsumer interface.", nameof(TConsumer));
        }

        services.TryAddSingleton<TConsumer>();

        services.AddTelemetryListeners();

        return services;
    }

    /// <summary>
    /// Registers a consumer singleton for every IMetricsConsumer interface it implements.
    /// </summary>
    public static IServiceCollection AddMetricsConsumer(this IServiceCollection services, object consumer)
    {
        var implementsAny = false;

        if (consumer is IMetricsConsumer<ForwarderMetrics> forwarderMetricsConsumer)
        {

View on GitHub (pinned to bd11867bee)

Solutions

  1. Decorate TConsumer with at least one I*TelemetryConsumer interface.
  2. If the type only implements IMetricsConsumer<...>, switch to AddMetricsConsumer<TConsumer>().
  3. Add a compile-time guard: `where TConsumer : IHttpClientTelemetryConsumer` on a custom wrapper if you want the error at build time.

Example fix

// before
public class MyConsumer { ... }
services.AddTelemetryConsumer<MyConsumer>();

// after
public class MyConsumer : ISocketsTelemetryConsumer { ... }
services.AddTelemetryConsumer<MyConsumer>();
Defensive patterns

Strategy: type-guard

Validate before calling

static bool ImplementsAnyTelemetryConsumer<T>() =>
    typeof(IHttpClientTelemetryConsumer).IsAssignableFrom(typeof(T))
    || typeof(ISocketsTelemetryConsumer).IsAssignableFrom(typeof(T))
    || typeof(INetSecurityTelemetryConsumer).IsAssignableFrom(typeof(T));

if (ImplementsAnyTelemetryConsumer<MyConsumer>())
    services.AddTelemetryConsumer<MyConsumer>();

Type guard

// Prefer a compile-time constraint on a custom wrapper:
public static IServiceCollection AddMyTelemetryConsumer<TConsumer>(this IServiceCollection services)
    where TConsumer : class, IHttpClientTelemetryConsumer
    => services.AddTelemetryConsumer<TConsumer>();

Prevention

When it happens

Trigger: Calling services.AddTelemetryConsumer<MyClass>() where MyClass does not implement any I*TelemetryConsumer interface. The error appears at startup during DI registration, not at compile time.

Common situations: Forgetting to add the interface to the consumer class; renaming the interface during a version upgrade so the class no longer satisfies it; passing a metrics-only type to the telemetry generic overload.

Related errors


AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13). Data as JSON: /api/errors/44e5fbebc48bd7ac. Report an issue: GitHub.