{"record":{"id":"e2401a913131d43e","repo":"dotnet/yarp","slug":"the-consumer-must-implement-at-least-one-i-telemet","errorCode":null,"errorMessage":"The consumer must implement at least one I*TelemetryConsumer interface.","messagePattern":"The consumer must implement at least one I\\*TelemetryConsumer interface\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/TelemetryConsumption/TelemetryConsumptionExtensions.cs","lineNumber":79,"sourceCode":"            services.TryAddEnumerable(ServiceDescriptor.Singleton(nameResolutionTelemetryConsumer));\n            implementsAny = true;\n        }\n\n        if (consumer is INetSecurityTelemetryConsumer netSecurityTelemetryConsumer)\n        {\n            services.TryAddEnumerable(ServiceDescriptor.Singleton(netSecurityTelemetryConsumer));\n            implementsAny = true;\n        }\n\n        if (consumer is ISocketsTelemetryConsumer socketsTelemetryConsumer)\n        {\n            services.TryAddEnumerable(ServiceDescriptor.Singleton(socketsTelemetryConsumer));\n            implementsAny = true;\n        }\n\n        if (!implementsAny)\n        {\n            throw new ArgumentException(\"The consumer must implement at least one I*TelemetryConsumer interface.\", nameof(consumer));\n        }\n\n        services.AddTelemetryListeners();\n\n        return services;\n    }\n\n    /// <summary>\n    /// Registers a <typeparamref name=\"TConsumer\"/> singleton for every I*TelemetryConsumer interface it implements.\n    /// </summary>\n    public static IServiceCollection AddTelemetryConsumer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TConsumer>(this IServiceCollection services)\n        where TConsumer : class\n    {\n        var implementsAny = false;\n\n        if (typeof(IWebSocketsTelemetryConsumer).IsAssignableFrom(typeof(TConsumer)))\n        {\n            services.AddSingleton(services => (IWebSocketsTelemetryConsumer)services.GetRequiredService<TConsumer>());","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/TelemetryConsumption/TelemetryConsumptionExtensions.cs#L61-L97","documentation":"AddTelemetryConsumer(object consumer) inspects the passed instance against every I*TelemetryConsumer interface (IHttpClientTelemetryConsumer, ISocketsTelemetryConsumer, INetSecurityTelemetryConsumer, etc.) and registers it for each one it implements. If none match, implementsAny stays false and it throws ArgumentException(paramName: consumer), because there is nothing to listen for.","triggerScenarios":"Calling services.AddTelemetryConsumer(someObject) where someObject's type does not implement any of the I*TelemetryConsumer interfaces, e.g. passing a plain class or a metrics-only consumer to the telemetry overload.","commonSituations":"Calling AddTelemetryConsumer with a class that only implements IMetricsConsumer<...> (wrong overload, should be AddMetricsConsumer); passing a consumer whose interfaces live in a different namespace; refactor that dropped the interface from the class declaration.","solutions":["Make the consumer implement at least one I*TelemetryConsumer interface (e.g. IHttpClientTelemetryConsumer).","If the consumer only handles metrics, call AddMetricsConsumer instead of AddTelemetryConsumer.","Prefer the generic AddTelemetryConsumer<TConsumer>() so the interface requirement is clearer, though it still validates at runtime."],"exampleFix":"// before\npublic class MyConsumer { ... }\nservices.AddTelemetryConsumer(new MyConsumer());\n\n// after\npublic class MyConsumer : IHttpClientTelemetryConsumer { ... }\nservices.AddTelemetryConsumer(new MyConsumer());","handlingStrategy":"type-guard","validationCode":"static bool ImplementsAnyTelemetryConsumer(object c) =>\n    c is IHttpClientTelemetryConsumer\n    || c is ISocketsTelemetryConsumer\n    || c is INetSecurityTelemetryConsumer;\n\nif (ImplementsAnyTelemetryConsumer(consumer))\n    services.AddTelemetryConsumer(consumer);","typeGuard":"static bool ImplementsAnyTelemetryConsumer(object c) =>\n    c is IHttpClientTelemetryConsumer\n    || c is ISocketsTelemetryConsumer\n    || c is INetSecurityTelemetryConsumer;","tryCatchPattern":null,"preventionTips":["Use the generic AddTelemetryConsumer<TConsumer>() with a class that has the interface so intent is explicit.","Keep telemetry consumers and metrics consumers in separate folders/namespaces to avoid passing one to the other's overload.","Add a unit test asserting each consumer type implements the expected interface."],"tags":["telemetry","di-registration","interface","validation","yarp"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}