{"record":{"id":"7facced162f2df86","repo":"grafana/k6","slug":"grpc-exporter-endpoint-is-required","errorCode":null,"errorMessage":"gRPC exporter endpoint is required","messagePattern":"gRPC exporter endpoint is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/output/opentelemetry/config.go","lineNumber":236,"sourceCode":"\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (cfg Config) validateExporterProtocol() error {\n\tif cfg.ExporterProtocol.String != \"\" {\n\t\tif cfg.ExporterProtocol.String != grpcExporterProtocol && cfg.ExporterProtocol.String != httpExporterProtocol {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"unsupported exporter protocol %q, only %q and %q are supported\",\n\t\t\t\tcfg.ExporterProtocol.String,\n\t\t\t\tgrpcExporterProtocol,\n\t\t\t\thttpExporterProtocol,\n\t\t\t)\n\t\t}\n\t\tswitch cfg.ExporterProtocol.String {\n\t\tcase grpcExporterProtocol:\n\t\t\tif cfg.GRPCExporterEndpoint.String == \"\" {\n\t\t\t\treturn errors.New(\"gRPC exporter endpoint is required\")\n\t\t\t}\n\t\tcase httpExporterProtocol:\n\t\t\tendpoint := cfg.HTTPExporterEndpoint.String\n\t\t\tif endpoint == \"\" {\n\t\t\t\treturn errors.New(\"HTTP exporter endpoint is required\")\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(endpoint, \"http://\") ||\n\t\t\t\tstrings.HasPrefix(endpoint, \"https://\") {\n\t\t\t\treturn errors.New(\"HTTP exporter endpoint must only be host and port, no scheme\")\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// String returns a string representation of the config\nfunc (cfg Config) String() string {","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/output/opentelemetry/config.go#L218-L254","documentation":"Thrown by Config.validateExporterProtocol() for the OpenTelemetry output when exporterProtocol is gRPC and the gRPC exporter endpoint is empty. Once the protocol is resolved to gRPC, an endpoint is mandatory because the OTLP gRPC exporter has no usable default in this output.","triggerScenarios":"Setting K6_OTEL_EXPORTER_PROTOCOL=grpc (or \"exporterProtocol\": \"grpc\") without K6_OTEL_GRPC_EXPORTER_ENDPOINT; unsetting the endpoint env var while keeping the protocol override; JSON output config with exporterProtocol grpc and no grpcExporterEndpoint field.","commonSituations":"Users switching from the default HTTP protocol to gRPC who set only the protocol flag; environment drift where the endpoint variable is defined in one CI stage but not the stage that runs k6; typos like K6_OTEL_GRPC_EXPORTER_ENDPONT.","solutions":["Set K6_OTEL_GRPC_EXPORTER_ENDPOINT, e.g. K6_OTEL_GRPC_EXPORTER_ENDPOINT=localhost:4317","Or pass it inline: -o experimental-opentelemetry=\"exporterProtocol=grpc,grpcExporterEndpoint=localhost:4317\"","Verify no typo in the env var name and that it is exported in the same shell/job that runs k6"],"exampleFix":"# before\nexport K6_OTEL_EXPORTER_PROTOCOL=grpc\n# no endpoint -> error\n\n# after\nexport K6_OTEL_EXPORTER_PROTOCOL=grpc\nexport K6_OTEL_GRPC_EXPORTER_ENDPOINT=localhost:4317","handlingStrategy":"validation","validationCode":"if [ \"${K6_OTEL_EXPORTER_PROTOCOL:-}\" = \"grpc\" ]; then\n  : \"${K6_OTEL_GRPC_EXPORTER_ENDPOINT:?K6_OTEL_GRPC_EXPORTER_ENDPOINT required for grpc protocol}\"\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair protocol and endpoint in the same config snippet; never set one without the other","Document the endpoint per environment (local collector vs production) in one place","Check for variable-name typos with env | grep K6_OTEL"],"tags":["k6","opentelemetry","otlp","grpc","endpoint","config"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}