{"record":{"id":"979a0f66930ad6f4","repo":"caddyserver/caddy","slug":"invalid-header-flag-v-979a0f","errorCode":null,"errorMessage":"invalid header flag: %v","messagePattern":"invalid header flag: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/staticresp.go","lineNumber":373,"sourceCode":"\t// if we still need a body, see if stdin is being piped\n\tif body == \"\" {\n\t\tstdinInfo, err := os.Stdin.Stat()\n\t\tif err != nil {\n\t\t\treturn caddy.ExitCodeFailedStartup, err\n\t\t}\n\t\tif stdinInfo.Mode()&os.ModeNamedPipe != 0 {\n\t\t\tbodyBytes, err := io.ReadAll(os.Stdin)\n\t\t\tif err != nil {\n\t\t\t\treturn caddy.ExitCodeFailedStartup, err\n\t\t\t}\n\t\t\tbody = string(bodyBytes)\n\t\t}\n\t}\n\n\t// build headers map\n\theaders, err := fl.GetStringArray(\"header\")\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"invalid header flag: %v\", err)\n\t}\n\thdr := make(http.Header)\n\tfor i, h := range headers {\n\t\tkey, val, found := strings.Cut(h, \":\")\n\t\tkey, val = strings.TrimSpace(key), strings.TrimSpace(val)\n\t\tif !found || key == \"\" || val == \"\" {\n\t\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"header %d: invalid format \\\"%s\\\" (expecting \\\"Field: value\\\")\", i, h)\n\t\t}\n\t\thdr.Set(key, val)\n\t}\n\n\t// build each HTTP server\n\thttpApp := App{Servers: make(map[string]*Server)}\n\n\t// expand listen address, if more than one port\n\tlistenAddr, err := caddy.ParseNetworkAddress(listen)\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, err","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/staticresp.go#L355-L391","documentation":"'caddy respond' reads repeated --header flags via fl.GetStringArray; this error wraps a failure of that flag lookup. It almost never fires from normal use — it indicates the flag was not registered/typed as a string slice in the running command context (e.g. a mismatched custom flag setup or embedded CLI misuse).","triggerScenarios":"Invoking cmdRespond through a custom caddycmd.Flags that did not define \"header\" as a string-array flag; binary/version mismatch between the CLI wrapper and command implementation.","commonSituations":"Embedding Caddy's CLI in another tool with a hand-built flag set; downgrading/mixing builds where the header flag registration changed.","solutions":["Use the stock 'caddy respond' command rather than a custom flag harness","If embedding, register the header flag with the same name and string-slice type before calling cmdRespond","Reinstall a consistent Caddy build to rule out mixed binaries"],"exampleFix":"// before (custom harness)\nfl := caddycmd.Flags{} // no header flag registered\n_, err := cmdRespond(fl)\n\n// after\nfl.RegisterStringArray(\"header\", \"\", \"\" /* ... */) // ensure 'header' is a []string flag","handlingStrategy":"validation","validationCode":"// when embedding the CLI, register the flag before invoking cmdRespond:\nfl := caddycmd.Flags{}\nfl.String(\"header\", \"\") // must match the type cmdRespond reads via GetStringArray\nif _, err := fl.GetStringArray(\"header\"); err != nil {\n    return fmt.Errorf(\"header flag misconfigured: %w\", err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the stock caddy binary for CLI commands unless embedding is required","Keep the flag definitions in custom harnesses in sync with the command implementation"],"tags":["caddy","cli","respond","flags","headers","embedding"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}