{"id":"e7dc29c1627cea94","repo":"aio-libs/aiohttp","slug":"too-many-trailers-received","errorCode":null,"errorMessage":"Too many trailers received","messagePattern":"Too many trailers received","errorType":"exception","errorClass":"BadHttpMessage","httpStatus":400,"severity":"error","filePath":"aiohttp/http_parser.py","lineNumber":1087,"sourceCode":"                                \"Bad trailer line ending, expected CRLF\"\n                            )\n                            set_exception(self.payload, exc)\n                            raise exc\n                        self._chunk_tail = chunk\n                        return PayloadState.PAYLOAD_NEEDS_INPUT, b\"\"\n\n                    line = chunk[:pos]\n                    chunk = chunk[pos + len(SEP) :]\n                    if SEP == b\"\\n\":  # For lax response parsing\n                        line = line.rstrip(b\"\\r\")\n\n                    if len(line) > self._max_field_size:\n                        raise LineTooLong(line[:100] + b\"...\", self._max_field_size)\n\n                    self._trailer_lines.append(line)\n\n                    if len(self._trailer_lines) > self._max_trailers:\n                        raise BadHttpMessage(\"Too many trailers received\")\n\n                    # \\r\\n\\r\\n found, end of stream\n                    if self._trailer_lines[-1] == b\"\":\n                        # Headers and trailers are defined the same way,\n                        # so we reuse the HeadersParser here.\n                        try:\n                            trailers, raw_trailers = self._headers_parser.parse_headers(\n                                self._trailer_lines\n                            )\n                        finally:\n                            self._trailer_lines.clear()\n                        self.payload.feed_eof()\n                        return PayloadState.PAYLOAD_COMPLETE, chunk\n\n        # Read all bytes until eof\n        elif self._type == ParseState.PARSE_UNTIL_EOF:\n            self._more_data_available = self.payload.feed_data(chunk)\n            while self._more_data_available:","sourceCodeStart":1069,"sourceCodeEnd":1105,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/http_parser.py#L1069-L1105","documentation":"BadHttpMessage('Too many trailers received') raised when the number of trailer lines accumulated after the zero-length chunk exceeds max_trailers (default 128). This protects against trailer flooding / memory exhaustion.","triggerScenarios":"A chunked message includes more than max_trailers trailer lines before the terminating blank line. Each appended trailer increments the count; once it exceeds max_trailers the parser raises.","commonSituations":"Adversarial peer flooding trailers; buggy sender never emitting the blank terminator so lines accumulate; max_trailers configured too low for a legit use; misbehaving intermediary appending many trailers.","solutions":["Increase max_trailers if many trailers are legitimate (configure the parser).","Ensure the sender terminates trailers with a blank CRLF line.","Reject/drop connections sending excessive trailers at the edge."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"from aiohttp.http_exceptions import BadHttpMessage\ntry:\n    await request.read()\nexcept BadHttpMessage as e:\n    if 'trailer' in e.message:\n        return web.Response(status=400)","preventionTips":["Set max_trailers to a sane cap and enforce it.","Don't forward unbounded trailers through your service."],"tags":["http","parser","chunked","trailers","limits","dos"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}