hyperium/hyper · error · std::io::Error
chunk trailers count overflow
Error message
chunk trailers count overflow
What it means
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.
Source
Thrown at src/proto/h1/decode.rs:563
match byte {
b'\r' => Poll::Ready(Ok(ChunkedState::TrailerLf)),
_ => Poll::Ready(Ok(ChunkedState::Trailer)),
}
}
fn read_trailer_lf<R: MemRead>(
cx: &mut Context<'_>,
rdr: &mut R,
trailers_buf: &mut Option<BytesMut>,
trailers_cnt: &mut usize,
h1_max_headers: usize,
h1_max_header_size: usize,
) -> Poll<Result<ChunkedState, io::Error>> {
let byte = byte!(rdr, cx);
match byte {
b'\n' => {
if *trailers_cnt >= h1_max_headers {
return Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidData,
"chunk trailers count overflow",
)));
}
*trailers_cnt += 1;
put_u8!(
trailers_buf.as_mut().expect("trailers_buf is None"),
byte,
h1_max_header_size
);
Poll::Ready(Ok(ChunkedState::EndCr))
}
_ => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid trailer end LF",
))),View on GitHub (pinned to 084473f728)
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).
Example fix
// before: default trailer header cap
let server = hyper::server::Server::bind(&addr).serve(make_svc);
// after: raise the h1 max-headers cap
let server = hyper::server::Server::bind(&addr)
.http1_max_headers(200)
.serve(make_svc); Defensive patterns
Strategy: validation
Validate before calling
// Configure the trailer-count cap to match what your peers legitimately send.
let server = hyper::server::Server::bind(&addr)
.http1_max_headers(expected_trailer_count + slack);
let client = hyper::Client::builder()
.http1_max_headers(expected_trailer_count + slack)
.build_http::<hyper::Body>(); Try / catch
Some(Err(e)) => {
if e.to_string().contains("chunk trailers count overflow") {
metrics::increment!("hyper.trailers.count_overflow");
tracing::warn!(error=%e, "too many trailers; raising h1_max_headers may be needed");
break;
}
return Err(e.into());
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Partial header
- chunk extensions over limit
- Invalid trailer end LF
- Invalid header name: {:?}
- Invalid header value: {:?}
AI-assisted analysis of hyperium/hyper@084473f728 (2026-08-06).
Data as JSON: /data/errors/763d512ae913e531.json.
Report an issue: GitHub.