quarkusio/quarkus · error · IllegalStateException

No OTLP protocol specified. Please check `quarkus.otel.expor

Error message

No OTLP protocol specified. Please check `quarkus.otel.exporter.otlp.traces.protocol` property

What it means

createSpanExporter requires a configured OTLP protocol for traces. When quarkus.otel.exporter.otlp.traces.protocol is empty/unset and the default is not resolvable, the recorder throws IllegalStateException('No OTLP protocol specified...'). The protocol selects between gRPC and HTTP/protobuf OTLP exporters.

Source

Thrown at extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/exporter/otlp/OTelExporterRecorder.java:112

                try {
                    TlsConfigurationRegistry tlsConfigurationRegistry = context
                            .getInjectedReference(TlsConfigurationRegistry.class);

                    return createSpanExporter(exporterRuntimeConfig.getValue(), vertx.get(), baseUri,
                            tlsConfigurationRegistry);

                } catch (IllegalArgumentException iae) {
                    throw new IllegalStateException("Unable to install OTLP Exporter", iae);
                }
            }

            private SpanExporter createSpanExporter(OtlpExporterRuntimeConfig exporterRuntimeConfig,
                    Vertx vertx,
                    URI baseUri,
                    TlsConfigurationRegistry tlsConfigurationRegistry) {
                OtlpExporterTracesConfig tracesConfig = exporterRuntimeConfig.traces();
                if (tracesConfig.protocol().isEmpty()) {
                    throw new IllegalStateException("No OTLP protocol specified. " +
                            "Please check `quarkus.otel.exporter.otlp.traces.protocol` property");
                }

                String protocol = tracesConfig.protocol().get();
                if (GRPC.equals(protocol)) {
                    return createOtlpGrpcSpanExporter(exporterRuntimeConfig, vertx, baseUri,
                            tlsConfigurationRegistry);
                } else if (HTTP_PROTOBUF.equals(protocol)) {
                    return createHttpSpanExporter(exporterRuntimeConfig, vertx, baseUri, protocol,
                            tlsConfigurationRegistry);
                }

                throw new IllegalArgumentException(String.format("Unsupported OTLP protocol %s specified. " +
                        "Please check `quarkus.otel.exporter.otlp.traces.protocol` property", protocol));
            }

            private SpanExporter createOtlpGrpcSpanExporter(OtlpExporterRuntimeConfig exporterRuntimeConfig,
                    Vertx vertx, final URI baseUri,

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set quarkus.otel.exporter.otlp.traces.protocol=grpc (or http/protobuf)
  2. Remove blank overrides from application.properties, env vars, or profile-specific configs
  3. Run with quarkus config dump to see which config source yields the empty value

Example fix

// before
quarkus.otel.exporter.otlp.traces.protocol=
// after
quarkus.otel.exporter.otlp.traces.protocol=grpc
Defensive patterns

Strategy: validation

Validate before calling

Optional<String> proto = ConfigProvider.getConfig()
    .getOptionalValue("quarkus.otel.exporter.otlp.traces.protocol", String.class);
if (proto.isEmpty()) {
    throw new IllegalStateException("Set quarkus.otel.exporter.otlp.traces.protocol=grpc or http/protobuf");
}

Type guard

static boolean tracesProtocolConfigured() {
    return ConfigProvider.getConfig()
        .getOptionalValue("quarkus.otel.exporter.otlp.traces.protocol", String.class)
        .filter(s -> !s.isBlank())
        .isPresent();
}

Try / catch

try {
    startApplication();
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().contains("No OTLP protocol specified")) {
        LOG.error("Set quarkus.otel.exporter.otlp.traces.protocol to grpc or http/protobuf");
    }
    throw e;
}

Prevention

When it happens

Trigger: Setting quarkus.otel.exporter.otlp.traces.protocol to an empty string (or a config source yielding empty) so Optional.isEmpty() is true in createSpanExporter, called from apply during startup.

Common situations: application.properties containing `quarkus.otel.exporter.otlp.traces.protocol=` (blank), an environment variable QUARKUS_OTEL_EXPORTER_OTLP_TRACES_PROTOCOL='' overriding a good default, or profile-specific config blanking the value.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/8197451e919465c1. Report an issue: GitHub.