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.metrics.protocol` property

What it means

The metrics exporter path requires quarkus.otel.exporter.otlp.metrics.protocol to be set; when it is empty the recorder throws IllegalStateException('No OTLP protocol specified. Please check `quarkus.otel.exporter.otlp.metrics.protocol` property'). This occurs while installing the OTLP metric exporter during startup when metrics are enabled.

Source

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

        final URI baseUri = getMetricsUri(exporterRuntimeConfig.getValue());

        return new Function<>() {
            @Override
            public MetricExporter apply(SyntheticCreationalContext<MetricExporter> context) {

                if (runtimeConfig.getValue().sdkDisabled() || baseUri == null) {
                    return NoopMetricExporter.INSTANCE;
                }

                MemoryMode memoryMode = exporterRuntimeConfig.getValue().memoryMode();
                MetricExporter metricExporter;

                try {
                    TlsConfigurationRegistry tlsConfigurationRegistry = context
                            .getInjectedReference(TlsConfigurationRegistry.class);
                    OtlpExporterMetricsConfig metricsConfig = exporterRuntimeConfig.getValue().metrics();
                    if (metricsConfig.protocol().isEmpty()) {
                        throw new IllegalStateException("No OTLP protocol specified. " +
                                "Please check `quarkus.otel.exporter.otlp.metrics.protocol` property");
                    }

                    String protocol = metricsConfig.protocol().get();
                    if (GRPC.equals(protocol)) {
                        metricExporter = new VertxGrpcMetricExporter(
                                new GrpcExporter(
                                        new VertxGrpcSender(
                                                baseUri,
                                                VertxGrpcSender.GRPC_METRIC_SERVICE_NAME,
                                                determineCompression(metricsConfig),
                                                metricsConfig.timeout(),
                                                populateTracingExportHttpHeaders(metricsConfig),
                                                new HttpClientOptionsConsumer(metricsConfig, baseUri, tlsConfigurationRegistry),
                                                vertx.get()),
                                        InternalTelemetryVersion.LATEST,
                                        ComponentId.generateLazy(OTLP_GRPC_METRIC_EXPORTER), // use the same as OTel does
                                        MeterProvider::noop,

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set quarkus.otel.exporter.otlp.metrics.protocol=grpc (or http/protobuf)
  2. Remove blank overrides of the metrics protocol from properties/env/profiles
  3. If metrics export is not wanted, set quarkus.otel.metrics.enabled=false

Example fix

// before
quarkus.otel.metrics.enabled=true
# metrics protocol missing
// after
quarkus.otel.metrics.enabled=true
quarkus.otel.exporter.otlp.metrics.protocol=grpc
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: quarkus.otel.metrics.enabled=true while quarkus.otel.exporter.otlp.metrics.protocol is unset or resolves to empty (blank property, empty env var, or profile override).

Common situations: Enabling metrics but only configuring the traces protocol (the metrics protocol is a separate property); blank env var QUARKUS_OTEL_EXPORTER_OTLP_METRICS_PROTOCOL='' overriding the default; copy-paste configs that forgot the metrics exporter block.

Related errors


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