{"record":{"id":"f8f21d513ceece10","repo":"aio-libs/aiohttp","slug":"invalid-content-length-header-content-length-hdr","errorCode":null,"errorMessage":"Invalid Content-Length header: {content_length_hdr!r}","messagePattern":"Invalid Content-Length header: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"aiohttp/client_reqrep.py","lineNumber":864,"sourceCode":"            self.headers[hdrs.AUTHORIZATION] = encode_basic_auth(\n                url.user or \"\", url.password or \"\"\n            )\n\n    def _reset_writer(self, _: object = None) -> None:\n        self._writer_task = None\n\n    def _get_content_length(self) -> int | None:\n        \"\"\"Extract and validate Content-Length header value.\n\n        Returns parsed Content-Length value or None if not set.\n        Raises ValueError if header exists but cannot be parsed as an integer.\n        \"\"\"\n        if hdrs.CONTENT_LENGTH not in self.headers:\n            return None\n\n        content_length_hdr = self.headers[hdrs.CONTENT_LENGTH]\n        if not _DIGITS_RE.fullmatch(content_length_hdr):\n            raise ValueError(f\"Invalid Content-Length header: {content_length_hdr!r}\")\n        return int(content_length_hdr)\n\n    @property\n    def _writer(self) -> asyncio.Task[None] | None:\n        return self._writer_task\n\n    @_writer.setter\n    def _writer(self, writer: asyncio.Task[None]) -> None:\n        if self._writer_task is not None:\n            self._writer_task.remove_done_callback(self._reset_writer)\n        self._writer_task = writer\n        writer.add_done_callback(self._reset_writer)\n\n    def is_ssl(self) -> bool:\n        return self.url.scheme in _SSL_SCHEMES\n\n    @property\n    def ssl(self) -> \"SSLContext | bool | Fingerprint\":","sourceCodeStart":846,"sourceCodeEnd":882,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/client_reqrep.py#L846-L882","documentation":"Raised by ClientRequest._get_content_length() when a manually-set Content-Length header value does not match _DIGITS_RE (one or more ASCII digits). Non-numeric, negative, fractional, or whitespace-containing values are rejected with ValueError. Headers set automatically from bodies are always valid; this fires only when a caller manually injects a malformed Content-Length.","triggerScenarios":"Manually setting headers['Content-Length'] to a non-integer string like 'abc', '12.5', '-1', ' 10 ', or '0x10' before sending. _get_content_length() runs the digits regex and raises ValueError.","commonSituations":"Injecting Content-Length from untrusted input without casting to int; copy-paste of a header value with units ('100 bytes'); locale/formatting producing non-ASCII digits; off-by-one string slicing corrupting the value.","solutions":["Let aiohttp set Content-Length automatically from the body — don't set it manually.","If you must set it, always use str(int(value)) to guarantee a clean integer string.","Validate the value is a non-negative integer before assigning to the header.","Remove any existing Content-Length header before re-setting it to avoid stale duplicates."],"exampleFix":"# before\nheaders['Content-Length'] = payload_size  # payload_size='12.5' -> ValueError\n\n# after\nheaders['Content-Length'] = str(int(payload_size))\n# or, better, omit the header and let aiohttp compute it from data=","handlingStrategy":"validation","validationCode":"def set_content_length(headers, value):\n    n = int(value)  # raises early if non-numeric\n    if n < 0:\n        raise ValueError('Content-Length must be non-negative')\n    headers['Content-Length'] = str(n)","typeGuard":"import re\n_DIGITS = re.compile(r'\\d+', re.ASCII)\ndef is_valid_content_length_header(value: str) -> bool:\n    return bool(_DIGITS.fullmatch(str(value)))","tryCatchPattern":"try:\n    await session.post(url, headers=headers, data=body)\nexcept ValueError as e:\n    if 'Content-Length' in str(e):\n        headers.pop('Content-Length', None)  # let aiohttp compute it\n        await session.post(url, headers=headers, data=body)\n    else:\n        raise","preventionTips":["Avoid setting Content-Length manually; let aiohttp derive it from the body.","Always coerce to int then str: str(int(value)).","Strip any stale Content-Length from templated headers."],"tags":["client","request","http-headers","validation","content-length"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}