{"record":{"id":"a3d0a27cc2cce80b","repo":"quarkusio/quarkus","slug":"no-otlp-protocol-specified-please-check-quarkus-a3d0a2","errorCode":null,"errorMessage":"No OTLP protocol specified. Please check `quarkus.otel.exporter.otlp.logs.protocol` property","messagePattern":"No OTLP protocol specified\\. Please check `quarkus\\.otel\\.exporter\\.otlp\\.logs\\.protocol` property","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/exporter/otlp/OTelExporterRecorder.java","lineNumber":279,"sourceCode":"        final URI baseUri = getLogsUri(exporterRuntimeConfig.getValue());\n\n        return new Function<>() {\n            @Override\n            public LogRecordExporter apply(SyntheticCreationalContext<LogRecordExporter> context) {\n\n                if (runtimeConfig.getValue().sdkDisabled() || baseUri == null) {\n                    return NoopLogRecordExporter.INSTANCE;\n                }\n\n                MemoryMode memoryMode = exporterRuntimeConfig.getValue().memoryMode();\n                LogRecordExporter logRecordExporter;\n\n                try {\n                    TlsConfigurationRegistry tlsConfigurationRegistry = context\n                            .getInjectedReference(TlsConfigurationRegistry.class);\n                    OtlpExporterLogsConfig logsConfig = exporterRuntimeConfig.getValue().logs();\n                    if (logsConfig.protocol().isEmpty()) {\n                        throw new IllegalStateException(\"No OTLP protocol specified. \" +\n                                \"Please check `quarkus.otel.exporter.otlp.logs.protocol` property\");\n                    }\n\n                    String protocol = logsConfig.protocol().get();\n                    if (GRPC.equals(protocol)) {\n                        logRecordExporter = new VertxGrpcLogRecordExporter(\n                                new GrpcExporter(\n                                        new VertxGrpcSender(\n                                                baseUri,\n                                                VertxGrpcSender.GRPC_LOG_SERVICE_NAME,\n                                                determineCompression(logsConfig),\n                                                logsConfig.timeout(),\n                                                populateTracingExportHttpHeaders(logsConfig),\n                                                new HttpClientOptionsConsumer(logsConfig, baseUri, tlsConfigurationRegistry),\n                                                vertx.get()),\n                                        InternalTelemetryVersion.LATEST,\n                                        ComponentId.generateLazy(\n                                                StandardComponentId.ExporterType.OTLP_GRPC_LOG_EXPORTER), // use the same as OTel does","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/exporter/otlp/OTelExporterRecorder.java#L261-L297","documentation":"Before creating the OTLP log record exporter, Quarkus requires an explicit protocol via `quarkus.otel.exporter.otlp.logs.protocol`. If the property is absent or empty, the recorder throws IllegalStateException because it cannot decide between the gRPC and HTTP senders. Unlike an unsupported value, this means nothing was configured at all.","triggerScenarios":"OTLP log export is enabled but `quarkus.otel.exporter.otlp.logs.protocol` is not set (or set to empty) in configuration.","commonSituations":"Adding the OpenTelemetry extension and enabling logs without completing the exporter config; migrating config where the logs protocol was omitted while the metrics/traces protocol existed; assuming a default that does not exist.","solutions":["Set `quarkus.otel.exporter.otlp.logs.protocol=http/protobuf`","Or set it to `grpc` if your collector endpoint speaks gRPC","If logs export is not wanted, disable it so no protocol is required"],"exampleFix":"# before\n# (no logs protocol configured)\n# after\nquarkus.otel.exporter.otlp.logs.protocol=http/protobuf","handlingStrategy":"validation","validationCode":"java.util.Optional<String> p = ConfigProvider.getConfig().getOptionalValue(\"quarkus.otel.exporter.otlp.logs.protocol\", String.class);\nif (p.isEmpty()) throw new IllegalStateException(\"Set quarkus.otel.exporter.otlp.logs.protocol (grpc | http/protobuf)\");","typeGuard":"static boolean logsProtocolConfigured(java.util.Optional<String> p) {\n    return p != null && p.isPresent() && !p.get().isBlank();\n}","tryCatchPattern":"try {\n    app.start();\n} catch (IllegalStateException e) {\n    if (String.valueOf(e.getMessage()).contains(\"No OTLP protocol specified\")) {\n        LOG.error(\"Add quarkus.otel.exporter.otlp.logs.protocol=http/protobuf\");\n    }\n}","preventionTips":["When enabling OTLP logs, always set the protocol property in the same change","Mirror the protocol already used for traces/metrics","Use Quarkus config validation / dev mode config warnings"],"tags":["opentelemetry","configuration","otlp","logging"],"backgroundTag":"missing-required-config","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}