quarkusio/quarkus · error · IllegalArgumentException

Unsupported OTLP protocol

Error message

Unsupported OTLP protocol %s specified. Please check `quarkus.otel.exporter.otlp.logs.protocol` property

What it means

The OTLP log exporter builder only supports `grpc` and `http/protobuf` protocols. If `quarkus.otel.exporter.otlp.logs.protocol` holds any other value, the recorder throws IllegalArgumentException (then wrapped as 'Unable to install OTLP Exporter'). This guards against silently configuring an exporter that cannot send data.

Solutions

  1. Set `quarkus.otel.exporter.otlp.logs.protocol=http/protobuf`
  2. Or set it to `grpc`
  3. Verify exact spelling and case of the protocol value
  4. Check you edited the `logs.protocol` key and not another signal's

Example fix

# before
quarkus.otel.exporter.otlp.logs.protocol=http/json
# after
quarkus.otel.exporter.otlp.logs.protocol=http/protobuf
Defensive patterns

Strategy: validation

Validate before calling

String p = ConfigProvider.getConfig().getValue("quarkus.otel.exporter.otlp.logs.protocol", String.class);
if (!"grpc".equals(p) && !"http/protobuf".equals(p)) {
    throw new IllegalArgumentException("quarkus.otel.exporter.otlp.logs.protocol must be grpc or http/protobuf, got: " + p);
}

Type guard

static boolean isSupportedOtlpProtocol(String p) {
    return "grpc".equals(p) || "http/protobuf".equals(p);
}

Try / catch

try {
    app.start();
} catch (IllegalStateException e) {
    if (e.getMessage().contains("Unable to install OTLP Exporter")) {
        LOG.error("Check quarkus.otel.exporter.otlp.logs.protocol (grpc | http/protobuf): " + e.getCause().getMessage());
    }
}

Prevention

When it happens

Trigger: Setting `quarkus.otel.exporter.otlp.logs.protocol` to anything besides `grpc` or `http/protobuf`, e.g. `http/json`, `otlp`, `grpc+tls`, or a misspelled value.

Common situations: Typos in properties files; values copied from the OTLP spec (`http/json` exists upstream but is not supported by Quarkus' exporters); mixing up metrics and logs protocol keys.

Related errors


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

Appendix: source

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

                                new HttpExporter(
                                        ComponentId.generateLazy(
                                                StandardComponentId.ExporterType.OTLP_HTTP_LOG_EXPORTER),
                                        new VertxHttpSender(
                                                baseUri,
                                                VertxHttpSender.LOGS_PATH,
                                                determineCompression(logsConfig),
                                                logsConfig.timeout(),
                                                populateTracingExportHttpHeaders(logsConfig),
                                                exportAsJson ? "application/json" : "application/x-protobuf",
                                                new HttpClientOptionsConsumer(logsConfig, baseUri, tlsConfigurationRegistry),
                                                vertx.get()),
                                        MeterProvider::noop,
                                        InternalTelemetryVersion.LATEST,
                                        baseUri,
                                        false),
                                memoryMode);
                    } else {
                        throw new IllegalArgumentException(String.format("Unsupported OTLP protocol %s specified. " +
                                "Please check `quarkus.otel.exporter.otlp.logs.protocol` property", protocol));
                    }

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

    private static DefaultAggregationSelector aggregationResolver(OtlpExporterMetricsConfig metricsConfig) {
        String defaultHistogramAggregation = metricsConfig.defaultHistogramAggregation()
                .map(s -> s.toLowerCase(Locale.ROOT))
                .orElse("explicit_bucket_histogram");

        DefaultAggregationSelector aggregationSelector;
        if (defaultHistogramAggregation.equals("explicit_bucket_histogram")) {

View on GitHub (pinned to e1c734241f)