{"record":{"id":"1d0e5b3f3fdc7a6c","repo":"grafana/k6","slug":"empty-header-key-received-q","errorCode":null,"errorMessage":"empty header key, received %q","messagePattern":"empty header key, received %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/file_persister.go","lineNumber":75,"sourceCode":"\n\t\t// A key with \"header.\" means that the header name is encoded in the\n\t\t// key, separated by a \".\". Split the header on \".\" to retrieve the\n\t\t// header name. The header value should be present in v from the previous\n\t\t// split.\n\t\tvar hv, hk string\n\t\tif strings.Contains(k, \"header.\") {\n\t\t\thv = v\n\n\t\t\thh := strings.Split(k, \".\")\n\t\t\tif len(hh) != 2 {\n\t\t\t\treturn presignedURLConfig{}, fmt.Errorf(\"format of header must be header.k=v, received %q\", s)\n\t\t\t}\n\n\t\t\tk = hh[0]\n\t\t\thk = hh[1]\n\n\t\t\tif hk == \"\" {\n\t\t\t\treturn presignedURLConfig{}, fmt.Errorf(\"empty header key, received %q\", s)\n\t\t\t}\n\t\t}\n\n\t\tswitch k {\n\t\tcase \"url\":\n\t\t\tu, err := url.ParseRequestURI(v)\n\t\t\tif err != nil && u.Scheme != \"\" && u.Host != \"\" {\n\t\t\t\treturn presignedURLConfig{}, fmt.Errorf(\"invalid url %q\", s)\n\t\t\t}\n\t\t\tpresignedURL.getterURL = v\n\t\tcase \"basePath\":\n\t\t\tpresignedURL.basePath = v\n\t\tcase \"header\":\n\t\t\tpresignedURL.headers[hk] = hv\n\t\tdefault:\n\t\t\treturn presignedURLConfig{}, fmt.Errorf(\"invalid option %q\", k)\n\t\t}\n\t}","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/browser/file_persister.go#L57-L93","documentation":"Returned while parsing K6_BROWSER_SCREENSHOTS_OUTPUT when a header entry has an empty header name: the key splits as 'header.' + '' (i.e. the value looks like 'header.=value'). The parser explicitly rejects an empty name after the dot.","triggerScenarios":"K6_BROWSER_SCREENSHOTS_OUTPUT containing 'header.=a' — a header key with nothing between 'header.' and the '='.","commonSituations":"Hand-building the variable with a placeholder header name that was never filled in; templating scripts (envsubst, Helm) that emit an empty variable into header.{{name}}.","solutions":["Provide a real header name: header.Authorization=xyz","Remove the header entry entirely if not needed","If the value is generated from a template, default the name to a placeholder like header.x=1 or drop the entry"],"exampleFix":"# before\nexport K6_BROWSER_SCREENSHOTS_OUTPUT='url=https://h/,header.=a'\n# after\nexport K6_BROWSER_SCREENSHOTS_OUTPUT='url=https://h/,header.authorization=a'","handlingStrategy":"validation","validationCode":"const v = process.env.K6_BROWSER_SCREENSHOTS_OUTPUT ?? '';\nif (v) {\n  const bad = v.split(',').filter(p => /^header\\.=/.test(p));\n  if (bad.length) throw new Error('header entries need a name: header.<name>=<value>');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never emit header.{{name}} from templates without defaulting the name","Prefer deleting unused header entries over leaving placeholders","Diff generated env values against the canonical example before deploy"],"tags":["k6","browser","screenshots","environment-variable","header"],"backgroundTag":"invalid-env-var-format","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"}