elsa-workflows/elsa-core · error · InvalidOperationException
OpenTelemetry gRPC ingestion is enabled, but no gRPC…
Error message
OpenTelemetry gRPC ingestion is enabled, but no gRPC endpoint path was configured.
What it means
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.
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.
Example fix
// before
services.AddOpenTelemetryDiagnostics(o => o.EnableGrpc = true);
// after
services.AddOpenTelemetryDiagnostics(o =>
{
o.EnableGrpc = true;
o.GrpcEndpointPath = "/opentelemetry/proto/collector/trace/v1/traces";
}); Defensive patterns
Strategy: validation
Validate before calling
var otel = app.Services.GetRequiredService<IOptions<OpenTelemetryDiagnosticsOptions>>().Value;
if (otel.EnableGrpc && string.IsNullOrWhiteSpace(otel.GrpcEndpointPath))
throw new InvalidOperationException("Set GrpcEndpointPath when EnableGrpc is true."); Prevention
- 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.
When it happens
Trigger: Configuring services.AddOpenTelemetryDiagnostics(o => o.EnableGrpc = true) (or setting EnableGrpc:true in appsettings) without setting GrpcEndpointPath, then calling MapOpenTelemetryGrpcCollector on the endpoint route builder.
Common situations: Partially copied sample configuration; appsettings section present but GrpcEndpointPath omitted; enabling gRPC ingestion via environment variables while the path key is missing or misspelled.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Register with configured before calling , or call with a…
- The console log provider registration is invalid.
- RequestBodyTooLargeException
- The OTLP timestamp is outside the supported range.
- Unsupported protobuf wire type
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/ba93a13f448bc839.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Diagnostics.OpenTelemetry/Extensions/EndpointRouteBuilderExtensions.cs:55
{
return await IngestAsync(httpContext, ingestor, options, payload => OtlpHttpProtobufParser.ParseMetrics(payload.Span), cancellationToken);
});
endpoints.MapPost($"{basePath}/logs", static async (HttpContext httpContext, IOpenTelemetryIngestor ingestor, IOptions<OpenTelemetryDiagnosticsOptions> options, CancellationToken cancellationToken) =>
{
return await IngestAsync(httpContext, ingestor, options, payload => OtlpHttpProtobufParser.ParseLogs(payload.Span), cancellationToken);
});
}
public static void MapOpenTelemetryGrpcCollector(this IEndpointRouteBuilder endpoints)
{
var options = endpoints.ServiceProvider.GetRequiredService<IOptions<OpenTelemetryDiagnosticsOptions>>().Value;
if (!options.EnableGrpc)
return;
if (string.IsNullOrWhiteSpace(options.GrpcEndpointPath))
throw new InvalidOperationException("OpenTelemetry gRPC ingestion is enabled, but no gRPC endpoint path was configured.");
// The actual gRPC service binding is host-specific. This module exposes shared ingestion
// contracts and accurate collector metadata without forcing every host to reference gRPC.
}
private static async Task<IResult> IngestAsync(
HttpContext httpContext,
IOpenTelemetryIngestor ingestor,
IOptions<OpenTelemetryDiagnosticsOptions> options,
Func<ReadOnlyMemory<byte>, OpenTelemetryBatch> parse,
CancellationToken cancellationToken)
{
if (!OtlpIngestionSecurity.IsAuthorized(httpContext, options.Value))
return Results.Unauthorized();
try
{
var payload = await ReadBodyAsync(httpContext, options.Value.MaxHttpRequestBodySize, cancellationToken);View on GitHub (pinned to fe9217bdfa)