{"record":{"id":"0d0ee84845f418d0","repo":"projectdiscovery/nuclei","slug":"invalid-header-line-s","errorCode":null,"errorMessage":"invalid header line: %s","messagePattern":"invalid header line: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/input/types/http.go","lineNumber":275,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse url: %s\", err)\n\t}\n\trr.URL = *urlx\n\n\t// parse headers\n\trr.Request.Headers = mapsutil.NewOrderedMap[string, string]()\n\tfor {\n\t\tline, err := protoReader.ReadLine()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read header line: %s\", err)\n\t\t}\n\t\tif line == \"\" {\n\t\t\t// end of headers next is body\n\t\t\tbreak\n\t\t}\n\t\tkey, value, found := strings.Cut(line, \":\")\n\t\tif !found || key == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"invalid header line: %s\", line)\n\t\t}\n\t\tvalue = strings.TrimSpace(value)\n\t\t// Host carries the authority rather than request metadata, and callers\n\t\t// read it off the URL: retryablehttp derives the wire Host from there,\n\t\t// and keeping it in the header map would expose it to header fuzzing as\n\t\t// if it were an ordinary header.\n\t\tif strings.EqualFold(key, \"Host\") {\n\t\t\t// an absolute request target takes precedence over the Host header\n\t\t\tif rr.URL.Host == \"\" {\n\t\t\t\trr.URL.Host = value\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\trr.Request.Headers.Set(key, value)\n\t}\n\n\t// parse body\n\trr.Request.Body = \"\"","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/input/types/http.go#L257-L293","documentation":"A header line inside the header block has no ':' separator or an empty key. After strings.Cut(line, ':'), either found==false (no colon at all) or key=='' (line starts with ':' or spaces before colon). 'Host:' is handled specially before this check and routed into URL.Host.","triggerScenarios":"Lines like 'Accept-Encoding gzip' (missing colon), ': value' (empty key), continuation/obsolete line folding lines starting with spaces, or a body line parsed as header because the blank separator line was misplaced.","commonSituations":"Manually editing headers and dropping colons; pasted multi-line header values (obs-fold) which this parser rejects; header names containing spaces.","solutions":["Format every header as 'Name: value' with a colon","Put long header values on a single line (line folding is not supported)","If the failing line looks like body content, add the blank line above it to end the header block"],"exampleFix":"# before\n  Accept-Encoding gzip\n\n# after\n  Accept-Encoding: gzip","handlingStrategy":"validation","validationCode":"for _, line := range headerLines {\n    if line == \"\" { break }\n    key, _, found := strings.Cut(line, \":\")\n    if !found || strings.TrimSpace(key) == \"\" {\n        return fmt.Errorf(\"malformed header line: %q\", line)\n    }\n}","typeGuard":null,"tryCatchPattern":"Catch, report the exact offending line (it is included in the message), fix the colon, and re-parse.","preventionTips":["Format headers as 'Name: value'","Keep long header values on one line (no obs-fold)","Note Host is special: it feeds URL.Host, not the header map"],"tags":["input","raw-http","parsing"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}