grafana/k6 · error
empty header key, received
Error message
empty header key, received %q
What it means
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.
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
Example fix
# before export K6_BROWSER_SCREENSHOTS_OUTPUT='url=https://h/,header.=a' # after export K6_BROWSER_SCREENSHOTS_OUTPUT='url=https://h/,header.authorization=a'
Defensive patterns
Strategy: validation
Validate before calling
const v = process.env.K6_BROWSER_SCREENSHOTS_OUTPUT ?? '';
if (v) {
const bad = v.split(',').filter(p => /^header\.=/.test(p));
if (bad.length) throw new Error('header entries need a name: header.<name>=<value>');
} Prevention
- 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
When it happens
Trigger: K6_BROWSER_SCREENSHOTS_OUTPUT containing 'header.=a' — a header key with nothing between 'header.' and the '='.
Common situations: 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}}.
Related errors
- format of header must be header.k=v, received
- format of value must be k=v, received
- invalid option
- invalid url
- parsing
AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18).
Data as JSON: /api/errors/1d0e5b3f3fdc7a6c.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/browser/file_persister.go:75
// A key with "header." means that the header name is encoded in the
// key, separated by a ".". Split the header on "." to retrieve the
// header name. The header value should be present in v from the previous
// split.
var hv, hk string
if strings.Contains(k, "header.") {
hv = v
hh := strings.Split(k, ".")
if len(hh) != 2 {
return presignedURLConfig{}, fmt.Errorf("format of header must be header.k=v, received %q", s)
}
k = hh[0]
hk = hh[1]
if hk == "" {
return presignedURLConfig{}, fmt.Errorf("empty header key, received %q", s)
}
}
switch k {
case "url":
u, err := url.ParseRequestURI(v)
if err != nil && u.Scheme != "" && u.Host != "" {
return presignedURLConfig{}, fmt.Errorf("invalid url %q", s)
}
presignedURL.getterURL = v
case "basePath":
presignedURL.basePath = v
case "header":
presignedURL.headers[hk] = hv
default:
return presignedURLConfig{}, fmt.Errorf("invalid option %q", k)
}
}View on GitHub (pinned to 01ffac6f24)