VictoriaMetrics/VictoriaMetrics · error
missing ':' in header %q; expecting "key: value" format
Error message
missing ':' in header %q; expecting "key: value" format
What it means
parseHeaders validates that every configured custom HTTP header is a string of the form "key: value" by locating the first colon. If a header string contains no colon, this error names the offending header. It is raised while building auth configs that accept a headers list (NewConfig, OAuth2 token_url headers, etc.).
Source
Thrown at lib/promauth/config.go:357
headers []keyValue
headersDigest string
}
type keyValue struct {
key string
value string
}
func parseHeaders(headers []string) ([]keyValue, error) {
if len(headers) == 0 {
return nil, nil
}
kvs := make([]keyValue, len(headers))
for i, h := range headers {
n := strings.IndexByte(h, ':')
if n < 0 {
return nil, fmt.Errorf(`missing ':' in header %q; expecting "key: value" format`, h)
}
kv := &kvs[i]
kv.key = http.CanonicalHeaderKey(strings.TrimSpace(h[:n]))
kv.value = strings.TrimSpace(h[n+1:])
}
return kvs, nil
}
// HeadersNoAuthString returns string representation of ac headers
func (ac *Config) HeadersNoAuthString() string {
if len(ac.headers) == 0 {
return ""
}
a := make([]string, len(ac.headers))
for i, h := range ac.headers {
a[i] = h.key + ": " + h.value + "\r\n"
}
return strings.Join(a, "")View on GitHub (pinned to 5079fb58f1)
Solutions
- Add the missing ':' separator to the named header so it reads "key: value".
- Quote each header string in YAML to prevent the parser from interpreting it as a mapping.
- Validate the headers block with a quick script checking every line contains ':' before deploying.
Example fix
// before headers: - "X-Scope-OrgID tenant-1" // after headers: - "X-Scope-OrgID: tenant-1"
Defensive patterns
Strategy: validation
Validate before calling
func validHeaders(headers []string) error {
for _, h := range headers {
if !strings.Contains(h, ":") {
return fmt.Errorf("header %q must be \"key: value\"", h)
}
}
return nil
} Try / catch
cfg, err := promauth.NewConfig(baseDir, opts)
if err != nil && strings.Contains(err.Error(), "missing ':' in header") {
// surface the config file and line to the operator
return fmt.Errorf("config headers block invalid: %w", err)
} Prevention
- Always write headers as quoted "Key: value" strings in YAML lists.
- Add CI linting that checks every headers entry contains a colon.
- Reuse the same parser/marshaller for header config everywhere.
When it happens
Trigger: Passing a headers slice such as []string{"Authorization Bearer xyz"} (space instead of colon) to NewConfig's Headers option or OAuth2Config.Headers.
Common situations: YAML list items written without the colon, or written with the colon swallowed by YAML syntax; copying `curl -H 'Authorization: x'` incorrectly; editors auto-stripping colons; tabs vs colon confusion.
Related errors
- path cannot be empty
- cannot parse months from %q: %w
- cannot parse headers for token_url: %w
- cannot use both `authorization` and `basic_auth`
- cannot simultaneously use `authorization`, `basic_auth` and
AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03).
Data as JSON: /api/errors/c490c18fb510fea0.
Report an issue: GitHub.