{"id":"763d512ae913e531","repo":"hyperium/hyper","slug":"chunk-trailers-count-overflow","errorCode":null,"errorMessage":"chunk trailers count overflow","messagePattern":"chunk trailers count overflow","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"src/proto/h1/decode.rs","lineNumber":563,"sourceCode":"        match byte {\n            b'\\r' => Poll::Ready(Ok(ChunkedState::TrailerLf)),\n            _ => Poll::Ready(Ok(ChunkedState::Trailer)),\n        }\n    }\n\n    fn read_trailer_lf<R: MemRead>(\n        cx: &mut Context<'_>,\n        rdr: &mut R,\n        trailers_buf: &mut Option<BytesMut>,\n        trailers_cnt: &mut usize,\n        h1_max_headers: usize,\n        h1_max_header_size: usize,\n    ) -> Poll<Result<ChunkedState, io::Error>> {\n        let byte = byte!(rdr, cx);\n        match byte {\n            b'\\n' => {\n                if *trailers_cnt >= h1_max_headers {\n                    return Poll::Ready(Err(io::Error::new(\n                        io::ErrorKind::InvalidData,\n                        \"chunk trailers count overflow\",\n                    )));\n                }\n                *trailers_cnt += 1;\n\n                put_u8!(\n                    trailers_buf.as_mut().expect(\"trailers_buf is None\"),\n                    byte,\n                    h1_max_header_size\n                );\n\n                Poll::Ready(Ok(ChunkedState::EndCr))\n            }\n            _ => Poll::Ready(Err(io::Error::new(\n                io::ErrorKind::InvalidInput,\n                \"Invalid trailer end LF\",\n            ))),","sourceCodeStart":545,"sourceCodeEnd":581,"githubUrl":"https://github.com/hyperium/hyper/blob/084473f728f9d07b3be5845475aa2f62ed9ff579/src/proto/h1/decode.rs#L545-L581","documentation":"Thrown in read_trailer_lf (src/proto/h1/decode.rs:563) when the count of trailer fields parsed after the final zero-length chunk reaches the configured h1_max_headers limit (default DEFAULT_MAX_HEADERS from the role module; configurable via hyper's h1_max_headers builder option). Each completed trailer line (CRLF) increments trailers_cnt, and exceeding the cap raises io::ErrorKind::InvalidData to bound memory use.","triggerScenarios":"A chunked body terminating with \"0\\r\\n\" followed by more trailer headers than h1_max_headers allows — e.g. a gRPC-style response that attaches dozens of metadata trailers when the server caps trailers at the default.","commonSituations":"Distributed-tracing or gRPC proxies that forward many metadata headers as trailers; raising security limits elsewhere while forgetting the trailer count cap; a malicious client flooding trailers.","solutions":["Raise the cap via hyper's builder if legitimate: Builder::http1_max_headers(N) (server) / http1_max_headers on the client builder when available.","Reduce the number of trailers the sender emits (aggregate metadata into fewer headers).","If the trailers are unexpected, investigate why the peer is sending them (proxy injecting headers after the body)."],"exampleFix":"// before: default trailer header cap\nlet server = hyper::server::Server::bind(&addr).serve(make_svc);\n\n// after: raise the h1 max-headers cap\nlet server = hyper::server::Server::bind(&addr)\n    .http1_max_headers(200)\n    .serve(make_svc);","handlingStrategy":"validation","validationCode":"// Configure the trailer-count cap to match what your peers legitimately send.\nlet server = hyper::server::Server::bind(&addr)\n    .http1_max_headers(expected_trailer_count + slack);\nlet client = hyper::Client::builder()\n    .http1_max_headers(expected_trailer_count + slack)\n    .build_http::<hyper::Body>();","typeGuard":null,"tryCatchPattern":"Some(Err(e)) => {\n    if e.to_string().contains(\"chunk trailers count overflow\") {\n        metrics::increment!(\"hyper.trailers.count_overflow\");\n        tracing::warn!(error=%e, \"too many trailers; raising h1_max_headers may be needed\");\n        break;\n    }\n    return Err(e.into());\n}","preventionTips":["Set h1_max_headers above the realistic number of trailers (server and client builders).","Aggregate peer metadata into fewer trailer fields where possible.","Investigate unexpected trailers — a proxy may be injecting headers after the body."],"tags":["http","http1","chunked","trailers","limits","hyper","rust"],"analyzedSha":"084473f728f9d07b3be5845475aa2f62ed9ff579","analyzedAt":"2026-08-06T01:20:18.522Z","schemaVersion":2}