{"record":{"id":"192ec574d4043d83","repo":"aio-libs/aiohttp","slug":"got-more-than-limit-bytes-when-reading-line-r-192ec5","errorCode":null,"errorMessage":"Got more than {limit} bytes when reading: {line!r}.","messagePattern":"Got more than (.+?) bytes when reading: (.+?)\\.","errorType":"exception","errorClass":"LineTooLong","httpStatus":null,"severity":"error","filePath":"aiohttp/streams.py","lineNumber":410,"sourceCode":"        chunk_size = 0\n        not_enough = True\n        max_size = max_size or self._high_water\n\n        while not_enough:\n            while self._buffer and not_enough:\n                offset = self._buffer_offset\n                ichar = self._buffer[0].find(separator, offset) + 1\n                # Read from current offset to found separator or to the end.\n                data = self._read_nowait_chunk(\n                    ichar - offset + seplen - 1 if ichar else -1\n                )\n                chunk += data\n                chunk_size += len(data)\n                if ichar:\n                    not_enough = False\n\n                if chunk_size > max_size:\n                    raise LineTooLong(chunk[:100] + b\"...\", max_size)\n\n            if self._eof:\n                break\n\n            if not_enough:\n                await self._wait(\"readuntil\")\n\n        if chunk and self._on_chunk_received is not None:\n            await self._fire_chunk_received(chunk)\n        return chunk\n\n    async def read(self, n: int = -1) -> bytes:\n        if self._exception is not None:\n            raise self._exception\n\n        if not n:\n            return b\"\"\n","sourceCodeStart":392,"sourceCodeEnd":428,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/streams.py#L392-L428","documentation":"Raised (as LineTooLong, a BadHttpMessage subclass) by StreamReader.readuntil when the accumulated chunk before the separator exceeds max_size bytes. The default max_size is the reader's high-water mark (2 * read_buf_size). This protects against unbounded memory growth from a missing delimiter or an oversized line. The message reports the limit and a truncated prefix of the offending data.","triggerScenarios":"Calling await stream.readuntil() / readline() on a stream whose next delimiter is farther than max_size bytes away; a server sending a very long header line or a binary blob with no newline; default high-water mark too small for legitimate payloads.","commonSituations":"Reading MIME/multipart boundaries that exceed the default limit; large JSON-lines payloads; binary protocols mistaken for line-based; default read buffer size left at 2**16.","solutions":["Pass an explicit larger limit: await stream.readuntil(max_size=10 * 1024 * 1024).","Increase the reader's buffer when constructing: StreamReader(..., read_buf_size=2**20).","Switch to chunked reads (await stream.read(n)) instead of delimiter-based reads for binary/large data."],"exampleFix":"# before\nline = await stream.readuntil(b'\\n')  # LineTooLong on big lines\n\n# after\nline = await stream.readuntil(b'\\n', max_size=16 * 1024 * 1024)","handlingStrategy":"validation","validationCode":"MAX = 16 * 1024 * 1024\nline = await stream.readuntil(b'\\n', max_size=MAX)","typeGuard":"def adequate_limit(stream, needed: int) -> bool:\n    return stream._high_water >= needed","tryCatchPattern":"from aiohttp.http_exceptions import LineTooLong\ntry:\n    line = await stream.readuntil(b'\\n')\nexcept LineTooLong:\n    line = await stream.readuntil(b'\\n', max_size=64 * 1024 * 1024)","preventionTips":["Pass explicit max_size matching your protocol's worst case.","Increase read_buf_size on the StreamReader for large line protocols.","Use chunked reads instead of line reads for binary/large data."],"tags":["streams","limits","parsing","memory"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}