{"id":"f4f58457f126ad17","repo":"hyperium/hyper","slug":"chunk-trailers-bytes-over-limit","errorCode":null,"errorMessage":"chunk trailers bytes over limit","messagePattern":"chunk trailers bytes over limit","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"src/proto/h1/decode.rs","lineNumber":281,"sourceCode":"\nmacro_rules! or_overflow {\n    ($e:expr) => (\n        match $e {\n            Some(val) => val,\n            None => return Poll::Ready(Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"invalid chunk size: overflow\",\n            ))),\n        }\n    )\n}\n\nmacro_rules! put_u8 {\n    ($trailers_buf:expr, $byte:expr, $limit:expr) => {\n        $trailers_buf.put_u8($byte);\n\n        if $trailers_buf.len() >= $limit {\n            return Poll::Ready(Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"chunk trailers bytes over limit\",\n            )));\n        }\n    };\n}\n\nstruct StepArgs<'a> {\n    chunk_size: &'a mut u64,\n    chunk_buf: &'a mut Option<Bytes>,\n    extensions_cnt: &'a mut u64,\n    trailers_buf: &'a mut Option<BytesMut>,\n    trailers_cnt: &'a mut usize,\n    max_headers_cnt: usize,\n    max_headers_bytes: usize,\n}\n\nimpl ChunkedState {","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/hyperium/hyper/blob/084473f728f9d07b3be5845475aa2f62ed9ff579/src/proto/h1/decode.rs#L263-L299","documentation":"Thrown in the HTTP/1 chunked decoder via the put_u8! macro (src/proto/h1/decode.rs:281) as io::Error::new(InvalidData, \"chunk trailers bytes over limit\"). It fires while accumulating the trailer section of a chunked body: each appended byte is checked and, once the trailers buffer reaches the limit, the error is returned. The default limit is TRAILER_LIMIT = 16 KiB (decode.rs:25), or h1_max_header_size if configured (decode.rs:181).","triggerScenarios":"The Trailer/TrailerLf/EndCr/EndLf states (decode.rs:327-337) append bytes with put_u8! (decode.rs:276-287); when the trailers buffer length reaches the configured max (TRAILER_LIMIT 16384 or a custom h1_max_header_size), the error fires. Triggered by a chunked body whose trailer headers exceed the cap.","commonSituations":"A client/server sends large trailer headers (big signature/checksum trailers); a misconfigured peer that puts real headers in trailers; an attacker abusing trailers to bypass head-size limits. Raising the trailer/header limit on the Builder raises the threshold.","solutions":["If large trailers are legitimate, raise the trailer limit via the HTTP/1 max header size / max headers configuration on the Builder.","Otherwise move that data into the message head (normal headers) or the body, and keep trailers small.","On the server, reject such requests with 431 and confirm the cap matches your policy."],"exampleFix":"// before: default 16 KiB trailer limit rejects legitimate large trailers\nlet mut http = hyper::server::conn::Http::new();\n\n// after: raise the per-header/trailer size limit to fit your workload\nlet mut http = hyper::server::conn::Http::new();\nhttp.max_buf_size(64 * 1024); // larger head+trailer buffer\n// and/or configure h1 max header size via the Builder options exposed by your version","handlingStrategy":"validation","validationCode":"// Enforce your own trailer-size policy before relying on hyper's 16 KiB default.\nfn trailers_within_policy(headers: &HeaderMap, max: usize) -> bool {\n    headers.iter().map(|(k, v)| k.as_str().len() + v.len() + 4).sum::<usize>() <= max\n}","typeGuard":"fn is_trailers_over_limit(err: &hyper::Error) -> bool {\n    matches!(\n        err.source().and_then(|s| s.downcast_ref::<std::io::Error>()).map(|io| io.kind()),\n        Some(std::io::ErrorKind::InvalidData)\n    )\n}","tryCatchPattern":"match hyper::body::to_bytes(req.into_body()).await {\n    Ok(b) => Ok(b),\n    Err(e) if is_trailers_over_limit(&e) => Ok(resp_431()), // trailers too large\n    Err(e) => Err(e),\n}","preventionTips":["Keep trailer headers small; move large metadata into normal headers or the body.","If large trailers are legitimate, raise the HTTP/1 header/trailer buffer on the Builder.","On a server, return 431 when trailers exceed policy so clients get a clear signal."],"tags":["http1","chunked","trailers","limits","rust"],"analyzedSha":"084473f728f9d07b3be5845475aa2f62ed9ff579","analyzedAt":"2026-08-06T01:20:18.522Z","schemaVersion":2}