{"record":{"id":"d97a47e0a160e92b","repo":"grafana/k6","slug":"format-of-header-must-be-header-k-v-received-q","errorCode":null,"errorMessage":"format of header must be header.k=v, received %q","messagePattern":"format of header must be header\\.k=v, received %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/file_persister.go","lineNumber":68,"sourceCode":"\t\tkv := strings.Split(s, \"=\")\n\t\tif len(kv) != 2 {\n\t\t\treturn presignedURLConfig{}, fmt.Errorf(\"format of value must be k=v, received %q\", s)\n\t\t}\n\n\t\tk := kv[0]\n\t\tv := kv[1]\n\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\":","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/browser/file_persister.go#L50-L86","documentation":"Returned while parsing K6_BROWSER_SCREENSHOTS_OUTPUT when a key containing 'header.' splits on '.' into something other than exactly 2 parts. Headers are encoded as header.<name>=<value>, so the key may have exactly one dot; extra dots (header..name, header.1.x) or a doubled dot produce this error.","triggerScenarios":"K6_BROWSER_SCREENSHOTS_OUTPUT containing 'header..asd=a' or 'header.x.custom=v' — keys where the literal 'header.' is followed by another dotted component.","commonSituations":"Trying to send a header whose intended name contains a dot (e.g. 'X-Custom.Sub') — the encoding scheme cannot express dotted header names; hand-editing the variable and slipping an extra dot.","solutions":["Use exactly one dot in header keys: header.Authorization=Bearer xyz","For header names that themselves contain a dot, replace the dot (e.g. dash) or encode it — the parser cannot carry a literal extra '.' in the name","Re-check the segment quoting the received value shown in the error"],"exampleFix":"# before\nexport K6_BROWSER_SCREENSHOTS_OUTPUT='url=https://h/,header..auth=token'\n# after\nexport K6_BROWSER_SCREENSHOTS_OUTPUT='url=https://h/,header.auth=token'","handlingStrategy":"validation","validationCode":"const v = process.env.K6_BROWSER_SCREENSHOTS_OUTPUT ?? '';\nif (v) {\n  const bad = v.split(',').filter(p => p.startsWith('header.') && p.split('=')[0].split('.').length !== 2);\n  if (bad.length) throw new Error(`header keys must be header.<name> with exactly one dot: ${bad.join(' | ')}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use exactly one dot in header keys","Do not attempt dotted header names in this encoding — rename them","Generate the variable from a script rather than by hand when headers proliferate"],"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"}