{"record":{"id":"1fa9ec9c82669274","repo":"aio-libs/aiohttp","slug":"invalid-http-header-hdr-r","errorCode":null,"errorMessage":"Invalid HTTP header: {hdr!r}","messagePattern":"Invalid HTTP header: (.+?)","errorType":"exception","errorClass":"InvalidHeader","httpStatus":400,"severity":"error","filePath":"aiohttp/http_parser.py","lineNumber":181,"sourceCode":"    def __init__(self, max_field_size: int = 8190, lax: bool = False) -> None:\n        self.max_field_size = max_field_size\n        self._lax = lax\n\n    def parse_headers(self, lines: list[bytes]) -> tuple[HeadersDictProxy, RawHeaders]:\n        headers: CIMultiDict[str] = CIMultiDict()\n        # note: \"raw\" does not mean inclusion of OWS before/after the field value\n        raw_headers = []\n\n        lines_idx = 0\n        line = lines[lines_idx]\n        line_count = len(lines)\n\n        while line:\n            # Parse initial header name : value pair.\n            try:\n                bname, bvalue = line.split(b\":\", 1)\n            except ValueError:\n                raise InvalidHeader(line) from None\n\n            if len(bname) == 0:\n                raise InvalidHeader(bname)\n\n            # https://www.rfc-editor.org/rfc/rfc9112.html#section-5.1-2\n            if {bname[0], bname[-1]} & {32, 9}:  # {\" \", \"\\t\"}\n                raise InvalidHeader(line)\n\n            bvalue = bvalue.lstrip(b\" \\t\")\n            name = bname.decode(\"utf-8\", \"surrogateescape\")\n            if not TOKENRE.fullmatch(name):\n                raise InvalidHeader(bname)\n\n            # next line\n            lines_idx += 1\n            line = lines[lines_idx]\n\n            # consume continuation lines","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/http_parser.py#L163-L199","documentation":"Raised by the header parser when a header line cannot be split on ':' (line.split(b':', 1) raises ValueError), i.e. the line contains no colon at all. RFC 9112 requires every field line be 'field-name \":\" OWS field-value'. The offending raw line (bytes) is included in the error.","triggerScenarios":"A client or server sends a header line with no ':' separator, e.g. 'Host example.com' (space instead of colon), or a stray line fed to the parser.","commonSituations":"Hand-crafted HTTP via raw sockets, broken/upstream proxies injecting malformed lines, HTTP-smuggling probes, or non-HTTP data being fed into the parser.","solutions":["Inspect the raw request/response bytes around the reported line.","Ensure every header line is 'name: value' with a literal colon.","Validate at the trust boundary (reverse proxy/WAF) before aiohttp sees the bytes."],"exampleFix":"# before\nsock.send(b'GET / HTTP/1.1\\r\\nHost example.com\\r\\n\\r\\n')\n\n# after\nsock.send(b'GET / HTTP/1.1\\r\\nHost: example.com\\r\\n\\r\\n')","handlingStrategy":"validation","validationCode":"def header_line_ok(line: bytes) -> bool:\n    # strict: name must be a token and a colon must separate name/value\n    return b':' in line and not line[:1].isspace()","typeGuard":"def has_colon_separator(line: bytes) -> bool:\n    return b':' in line","tryCatchPattern":"from aiohttp.http_exceptions import InvalidHeader, BadHttpMessage\ntry:\n    await parser.feed_data(raw)\nexcept (InvalidHeader, BadHttpMessage) as e:\n    # close the malformed connection, log the peer\n    ...","preventionTips":["When building HTTP by hand, always use 'name: value' form.","Don't feed non-HTTP byte streams into the HTTP parser."],"tags":["http","parser","header","request","validation"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}