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

  1. Add the missing ':' separator to the named header so it reads "key: value".
  2. Quote each header string in YAML to prevent the parser from interpreting it as a mapping.
  3. 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

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


AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03). Data as JSON: /api/errors/c490c18fb510fea0. Report an issue: GitHub.