{"record":{"id":"177a9a05a007dd3f","repo":"grafana/k6","slug":"providing-service-name-is-required","errorCode":null,"errorMessage":"providing service name is required","messagePattern":"providing service name is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/output/opentelemetry/config.go","lineNumber":210,"sourceCode":"\tif v.Headers.Valid {\n\t\tcfg.Headers = v.Headers\n\t}\n\n\tif v.HTTPUsername.Valid {\n\t\tcfg.HTTPUsername = v.HTTPUsername\n\t}\n\n\tif v.HTTPPassword.Valid {\n\t\tcfg.HTTPPassword = v.HTTPPassword\n\t}\n\n\treturn cfg\n}\n\n// Validate validates the config\nfunc (cfg Config) Validate() error {\n\tif cfg.ServiceName.String == \"\" {\n\t\treturn errors.New(\"providing service name is required\")\n\t}\n\t// TODO: it's not actually required, but we should probably have a default\n\t// check if it works without it\n\tif cfg.ServiceVersion.String == \"\" {\n\t\treturn errors.New(\"providing service version is required\")\n\t}\n\tif err := cfg.validateExporterProtocol(); err != nil {\n\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,","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/output/opentelemetry/config.go#L192-L228","documentation":"The OpenTelemetry metrics output requires a service name for the exported resource. k6 ships a default ('k6'), but Validate() rejects the config when ServiceName.String is empty — which in practice happens when K6_OTEL_SERVICE_NAME or the JSON output config overrides the default with an empty string (empty env vars still count as Valid overrides).","triggerScenarios":"export K6_OTEL_SERVICE_NAME= (defined but empty, common in CI matrices); an output config JSON with \"serviceName\": \"\".","commonSituations":"CI systems that predefine placeholder variables as empty strings; parameterized pipelines where the service-name variable is populated per-job and this job missed it.","solutions":["Set a real value, e.g. export K6_OTEL_SERVICE_NAME=my-service","Remove the empty K6_OTEL_SERVICE_NAME from the environment so the 'k6' default applies","Guard CI templates to skip exporting the variable when its value is empty"],"exampleFix":"# before\nexport K6_OTEL_SERVICE_NAME=    # accidentally empty\nk6 run -o opentelemetry script.js\n# after\nexport K6_OTEL_SERVICE_NAME=checkout-api\nk6 run -o opentelemetry script.js","handlingStrategy":"validation","validationCode":"// Shell: treat empty as unset\n: \"${K6_OTEL_SERVICE_NAME:=k6}\"\nexport K6_OTEL_SERVICE_NAME\nk6 run -o opentelemetry script.js","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default OTel env vars in a shared profile instead of exporting blanks from CI matrices","Check defined-but-empty variables before every k6 cloud/OTel run","Name services per component (e.g. checkout-api) so metrics are filterable"],"tags":["opentelemetry","observability","configuration","environment-variables","k6"],"backgroundTag":"empty-env-var-override","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}