{"record":{"id":"c490c18fb510fea0","repo":"VictoriaMetrics/VictoriaMetrics","slug":"missing-in-header-q-expecting-key-value-f","errorCode":null,"errorMessage":"missing ':' in header %q; expecting \"key: value\" format","messagePattern":"missing ':' in header %q; expecting \"key: value\" format","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/promauth/config.go","lineNumber":357,"sourceCode":"\n\theaders       []keyValue\n\theadersDigest string\n}\n\ntype keyValue struct {\n\tkey   string\n\tvalue string\n}\n\nfunc parseHeaders(headers []string) ([]keyValue, error) {\n\tif len(headers) == 0 {\n\t\treturn nil, nil\n\t}\n\tkvs := make([]keyValue, len(headers))\n\tfor i, h := range headers {\n\t\tn := strings.IndexByte(h, ':')\n\t\tif n < 0 {\n\t\t\treturn nil, fmt.Errorf(`missing ':' in header %q; expecting \"key: value\" format`, h)\n\t\t}\n\t\tkv := &kvs[i]\n\t\tkv.key = http.CanonicalHeaderKey(strings.TrimSpace(h[:n]))\n\t\tkv.value = strings.TrimSpace(h[n+1:])\n\t}\n\treturn kvs, nil\n}\n\n// HeadersNoAuthString returns string representation of ac headers\nfunc (ac *Config) HeadersNoAuthString() string {\n\tif len(ac.headers) == 0 {\n\t\treturn \"\"\n\t}\n\ta := make([]string, len(ac.headers))\n\tfor i, h := range ac.headers {\n\t\ta[i] = h.key + \": \" + h.value + \"\\r\\n\"\n\t}\n\treturn strings.Join(a, \"\")","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/promauth/config.go#L339-L375","documentation":"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.).","triggerScenarios":"Passing a headers slice such as []string{\"Authorization Bearer xyz\"} (space instead of colon) to NewConfig's Headers option or OAuth2Config.Headers.","commonSituations":"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.","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."],"exampleFix":"// before\nheaders:\n  - \"X-Scope-OrgID tenant-1\"\n// after\nheaders:\n  - \"X-Scope-OrgID: tenant-1\"","handlingStrategy":"validation","validationCode":"func validHeaders(headers []string) error {\n    for _, h := range headers {\n        if !strings.Contains(h, \":\") {\n            return fmt.Errorf(\"header %q must be \\\"key: value\\\"\", h)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"cfg, err := promauth.NewConfig(baseDir, opts)\nif err != nil && strings.Contains(err.Error(), \"missing ':' in header\") {\n    // surface the config file and line to the operator\n    return fmt.Errorf(\"config headers block invalid: %w\", err)\n}","preventionTips":["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."],"tags":["config","http-headers","validation"],"backgroundTag":"invalid-http-header-config","analyzedSha":"5079fb58f1e8e62113f90c945ad71586c797d770","analyzedAt":"2026-09-03T18:10:26.153Z","contentChangedAt":"2026-09-03T18:10:26.153Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}