{"record":{"id":"90bcc1175c2e2dcc","repo":"quarkusio/quarkus","slug":"no-otlp-protocol-specified-please-check-quarkus-90bcc1","errorCode":null,"errorMessage":"No OTLP protocol specified. Please check `quarkus.otel.exporter.otlp.metrics.protocol` property","messagePattern":"No OTLP protocol specified\\. Please check `quarkus\\.otel\\.exporter\\.otlp\\.metrics\\.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":201,"sourceCode":"        final URI baseUri = getMetricsUri(exporterRuntimeConfig.getValue());\n\n        return new Function<>() {\n            @Override\n            public MetricExporter apply(SyntheticCreationalContext<MetricExporter> context) {\n\n                if (runtimeConfig.getValue().sdkDisabled() || baseUri == null) {\n                    return NoopMetricExporter.INSTANCE;\n                }\n\n                MemoryMode memoryMode = exporterRuntimeConfig.getValue().memoryMode();\n                MetricExporter metricExporter;\n\n                try {\n                    TlsConfigurationRegistry tlsConfigurationRegistry = context\n                            .getInjectedReference(TlsConfigurationRegistry.class);\n                    OtlpExporterMetricsConfig metricsConfig = exporterRuntimeConfig.getValue().metrics();\n                    if (metricsConfig.protocol().isEmpty()) {\n                        throw new IllegalStateException(\"No OTLP protocol specified. \" +\n                                \"Please check `quarkus.otel.exporter.otlp.metrics.protocol` property\");\n                    }\n\n                    String protocol = metricsConfig.protocol().get();\n                    if (GRPC.equals(protocol)) {\n                        metricExporter = new VertxGrpcMetricExporter(\n                                new GrpcExporter(\n                                        new VertxGrpcSender(\n                                                baseUri,\n                                                VertxGrpcSender.GRPC_METRIC_SERVICE_NAME,\n                                                determineCompression(metricsConfig),\n                                                metricsConfig.timeout(),\n                                                populateTracingExportHttpHeaders(metricsConfig),\n                                                new HttpClientOptionsConsumer(metricsConfig, baseUri, tlsConfigurationRegistry),\n                                                vertx.get()),\n                                        InternalTelemetryVersion.LATEST,\n                                        ComponentId.generateLazy(OTLP_GRPC_METRIC_EXPORTER), // use the same as OTel does\n                                        MeterProvider::noop,","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/exporter/otlp/OTelExporterRecorder.java#L183-L219","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Set quarkus.otel.exporter.otlp.metrics.protocol=grpc (or http/protobuf)","Remove blank overrides of the metrics protocol from properties/env/profiles","If metrics export is not wanted, set quarkus.otel.metrics.enabled=false"],"exampleFix":"// before\nquarkus.otel.metrics.enabled=true\n# metrics protocol missing\n// after\nquarkus.otel.metrics.enabled=true\nquarkus.otel.exporter.otlp.metrics.protocol=grpc","handlingStrategy":"validation","validationCode":"Optional<String> proto = ConfigProvider.getConfig()\n    .getOptionalValue(\"quarkus.otel.exporter.otlp.metrics.protocol\", String.class);\nif (proto.isEmpty()) {\n    throw new IllegalStateException(\"Set quarkus.otel.exporter.otlp.metrics.protocol=grpc or http/protobuf\");\n}","typeGuard":"static boolean metricsProtocolConfigured() {\n    return ConfigProvider.getConfig()\n        .getOptionalValue(\"quarkus.otel.exporter.otlp.metrics.protocol\", String.class)\n        .filter(s -> !s.isBlank())\n        .isPresent();\n}","tryCatchPattern":"try {\n    startApplication();\n} catch (IllegalStateException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"otlp.metrics.protocol\")) {\n        LOG.error(\"Set quarkus.otel.exporter.otlp.metrics.protocol to grpc or http/protobuf\");\n    }\n    throw e;\n}","preventionTips":["Configure metrics protocol independently of traces protocol when enabling metrics","Blank env vars override defaults — check QUARKUS_OTEL_EXPORTER_OTLP_METRICS_PROTOCOL","Set quarkus.otel.metrics.enabled=false if metrics export is not used","Keep traces and metrics exporter blocks in config templates together"],"tags":["opentelemetry","otlp","config","metrics"],"backgroundTag":"missing-config-property","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"}