{"record":{"id":"48965d4341893cb1","repo":"caddyserver/caddy","slug":"header-down-d-invalid-format-s-expecting-fi","errorCode":null,"errorMessage":"header-down %d: invalid format \"%s\" (expecting \"Field: value\")","messagePattern":"header-down (.+?): invalid format \"(.+?)\" \\(expecting \"Field: value\"\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/reverseproxy/command.go","lineNumber":217,"sourceCode":"\t\thandler.Headers = &headers.Handler{\n\t\t\tRequest: &headers.HeaderOps{\n\t\t\t\tSet: reqHdr,\n\t\t\t},\n\t\t}\n\t}\n\n\t// set up header_down\n\theaderDown, err := fs.GetStringArray(\"header-down\")\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"invalid header flag: %v\", err)\n\t}\n\tif len(headerDown) > 0 {\n\t\trespHdr := make(http.Header)\n\t\tfor i, h := range headerDown {\n\t\t\tkey, val, found := strings.Cut(h, \":\")\n\t\t\tkey, val = strings.TrimSpace(key), strings.TrimSpace(val)\n\t\t\tif !found || key == \"\" || val == \"\" {\n\t\t\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"header-down %d: invalid format \\\"%s\\\" (expecting \\\"Field: value\\\")\", i, h)\n\t\t\t}\n\t\t\trespHdr.Set(key, val)\n\t\t}\n\t\tif handler.Headers == nil {\n\t\t\thandler.Headers = &headers.Handler{}\n\t\t}\n\t\thandler.Headers.Response = &headers.RespHeaderOps{\n\t\t\tHeaderOps: &headers.HeaderOps{\n\t\t\t\tSet: respHdr,\n\t\t\t},\n\t\t}\n\t}\n\n\tif changeHost {\n\t\tif handler.Headers == nil {\n\t\t\thandler.Headers = new(headers.Handler)\n\t\t}\n\t\tif handler.Headers.Request == nil {","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/reverseproxy/command.go#L199-L235","documentation":"Each `--header-down` value is validated as `\"Field: value\"` using `strings.Cut` on the first colon. Missing colon, empty field name, or empty value (after TrimSpace) aborts startup with the 0-based index and raw string in the message.","triggerScenarios":"`--header-down \"Set-Cookie\"` (no colon), `--header-down \"X-Y: \"` (empty value), or `--header-down \":v\"` (empty name).","commonSituations":"Attempting to just declare a response header without a value, or environment-driven values that are empty at launch time.","solutions":["Format the value as \"Field: value\" with both parts non-empty","Verify environment variables used in the value are exported in the shell launching caddy","Use the reported index to locate the exact offending argument"],"exampleFix":"# before\ncaddy reverse-proxy --to localhost:9000 --header-down \"Cache-Control\"\n# after\ncaddy reverse-proxy --to localhost:9000 --header-down \"Cache-Control: no-cache\"","handlingStrategy":"validation","validationCode":"for i, h := range headerDowns {\n\tkey, val, found := strings.Cut(h, \":\")\n\tif !found || strings.TrimSpace(key) == \"\" || strings.TrimSpace(val) == \"\" {\n\t\treturn fmt.Errorf(\"header-down %d invalid: %q\", i, h)\n\t}\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provide a non-empty value; there is no valueless form for these CLI flags","Check env expansion results before launch: printf '%s\\n' \"$HDR\""],"tags":["cli","reverse-proxy","headers","validation"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}