{"record":{"id":"ba93a13f448bc839","repo":"elsa-workflows/elsa-core","slug":"opentelemetry-grpc-ingestion-is-enabled-but-no-grpc-endpoint","errorCode":null,"errorMessage":"OpenTelemetry gRPC ingestion is enabled, but no gRPC endpoint path was configured.","messagePattern":"OpenTelemetry gRPC ingestion is enabled, but no gRPC endpoint path was configured\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Diagnostics.OpenTelemetry/Extensions/EndpointRouteBuilderExtensions.cs","lineNumber":55,"sourceCode":"        {\n            return await IngestAsync(httpContext, ingestor, options, payload => OtlpHttpProtobufParser.ParseMetrics(payload.Span), cancellationToken);\n        });\n\n        endpoints.MapPost($\"{basePath}/logs\", static async (HttpContext httpContext, IOpenTelemetryIngestor ingestor, IOptions<OpenTelemetryDiagnosticsOptions> options, CancellationToken cancellationToken) =>\n        {\n            return await IngestAsync(httpContext, ingestor, options, payload => OtlpHttpProtobufParser.ParseLogs(payload.Span), cancellationToken);\n        });\n    }\n\n    public static void MapOpenTelemetryGrpcCollector(this IEndpointRouteBuilder endpoints)\n    {\n        var options = endpoints.ServiceProvider.GetRequiredService<IOptions<OpenTelemetryDiagnosticsOptions>>().Value;\n\n        if (!options.EnableGrpc)\n            return;\n\n        if (string.IsNullOrWhiteSpace(options.GrpcEndpointPath))\n            throw new InvalidOperationException(\"OpenTelemetry gRPC ingestion is enabled, but no gRPC endpoint path was configured.\");\n\n        // The actual gRPC service binding is host-specific. This module exposes shared ingestion\n        // contracts and accurate collector metadata without forcing every host to reference gRPC.\n    }\n\n    private static async Task<IResult> IngestAsync(\n        HttpContext httpContext,\n        IOpenTelemetryIngestor ingestor,\n        IOptions<OpenTelemetryDiagnosticsOptions> options,\n        Func<ReadOnlyMemory<byte>, OpenTelemetryBatch> parse,\n        CancellationToken cancellationToken)\n    {\n        if (!OtlpIngestionSecurity.IsAuthorized(httpContext, options.Value))\n            return Results.Unauthorized();\n\n        try\n        {\n            var payload = await ReadBodyAsync(httpContext, options.Value.MaxHttpRequestBodySize, cancellationToken);","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Diagnostics.OpenTelemetry/Extensions/EndpointRouteBuilderExtensions.cs#L37-L73","documentation":"MapOpenTelemetryGrpcCollector is a startup-time endpoint mapper for the OpenTelemetry diagnostics module. If OpenTelemetryDiagnosticsOptions.EnableGrpc is true but GrpcEndpointPath is null/whitespace, the module has no route to bind the OTLP gRPC collector, so it throws InvalidOperationException during endpoint mapping rather than silently skipping ingestion.","triggerScenarios":"Configuring services.AddOpenTelemetryDiagnostics(o => o.EnableGrpc = true) (or setting EnableGrpc:true in appsettings) without setting GrpcEndpointPath, then calling MapOpenTelemetryGrpcCollector on the endpoint route builder.","commonSituations":"Partially copied sample configuration; appsettings section present but GrpcEndpointPath omitted; enabling gRPC ingestion via environment variables while the path key is missing or misspelled.","solutions":["Set GrpcEndpointPath to a valid path, e.g. o.GrpcEndpointPath = \"/opentelemetry/proto/collector/trace/v1/traces\";.","If gRPC ingestion is not needed, explicitly set EnableGrpc = false so the mapper short-circuits.","Verify the configuration binding key in appsettings/environment matches the GrpcEndpointPath property."],"exampleFix":"// before\nservices.AddOpenTelemetryDiagnostics(o => o.EnableGrpc = true);\n\n// after\nservices.AddOpenTelemetryDiagnostics(o =>\n{\n    o.EnableGrpc = true;\n    o.GrpcEndpointPath = \"/opentelemetry/proto/collector/trace/v1/traces\";\n});","handlingStrategy":"validation","validationCode":"var otel = app.Services.GetRequiredService<IOptions<OpenTelemetryDiagnosticsOptions>>().Value;\nif (otel.EnableGrpc && string.IsNullOrWhiteSpace(otel.GrpcEndpointPath))\n    throw new InvalidOperationException(\"Set GrpcEndpointPath when EnableGrpc is true.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When enabling EnableGrpc, always set GrpcEndpointPath in the same configuration block.","Validate options at startup with IValidateOptions/options validation so misconfigurations fail fast with a clear message."],"tags":["configuration","opentelemetry","startup","grpc"],"backgroundTag":"missing-required-config-field","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}