hyperium/hyper · error · std::io::Error
chunk extensions over limit
Error message
chunk extensions over limit
What it means
Thrown in read_extension (src/proto/h1/decode.rs:444) when the running total of chunk-extension bytes (extensions_cnt) reaches CHUNKED_EXTENSIONS_LIMIT, a hard-coded 16 KiB cap applied across the whole body (see decode.rs:20). hyper does not parse extensions but bounds them to limit memory/wire abuse. Reported as io::ErrorKind::InvalidData.
Source
Thrown at src/proto/h1/decode.rs:444
extensions_cnt: &mut u64,
) -> Poll<Result<ChunkedState, io::Error>> {
trace!("read_extension");
// We don't care about extensions really at all. Just ignore them.
// They "end" at the next CRLF.
//
// However, some implementations may not check for the CR, so to save
// them from themselves, we reject extensions containing plain LF as
// well.
match byte!(rdr, cx) {
b'\r' => Poll::Ready(Ok(ChunkedState::SizeLf)),
b'\n' => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidData,
"invalid chunk extension contains newline",
))),
_ => {
*extensions_cnt += 1;
if *extensions_cnt >= CHUNKED_EXTENSIONS_LIMIT {
Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidData,
"chunk extensions over limit",
)))
} else {
Poll::Ready(Ok(ChunkedState::Extension))
}
} // no supported extensions
}
}
fn read_size_lf<R: MemRead>(
cx: &mut Context<'_>,
rdr: &mut R,
size: u64,
) -> Poll<Result<ChunkedState, io::Error>> {
trace!("Chunk size is {:?}", size);
match byte!(rdr, cx) {
b'\n' => {
if size == 0 {View on GitHub (pinned to 084473f728)
Solutions
- Move large per-chunk metadata out of chunk extensions and into trailers or the body itself.
- Reduce the number of chunks (batch data) so extensions aren't repeated hundreds of times.
- If you are on the receiving side and the limit is a defense, leave it; if you genuinely need more, the limit is a const (CHUNKED_EXTENSIONS_LIMIT) and requires a hyper patch/rebuild.
- Front the service with a proxy that strips oversized extensions before they reach hyper.
Example fix
// before: stuffing trace context into every chunk extension
for part in parts {
write!(w, "{:x};trace={}\r\n", part.len(), huge_trace).await?;
w.write_all(&part).await?;
write!(w, "\r\n").await?;
}
// after: send trace once as a trailer
write!(w, "0\r\ntrace: {}\r\n\r\n", huge_trace).await?; Defensive patterns
Strategy: try-catch
Validate before calling
// When emitting many chunks, keep total extension bytes under 16 KiB.
const EXT_BUDGET: u64 = 16 * 1024;
let mut spent: u64 = 0;
for part in parts {
let ext_len = trace_str.len() as u64;
if spent + ext_len >= EXT_BUDGET {
// stop emitting extensions; rely on a trailer instead
write!(w, "{:x}\r\n", part.len()).await?;
} else {
write!(w, "{:x};t={}\r\n", part.len(), trace_str).await?;
spent += ext_len;
}
} Try / catch
Some(Err(e)) => {
if e.to_string().contains("chunk extensions over limit") {
metrics::increment!("hyper.chunked.ext_over_limit");
tracing::warn!(error=%e, "peer exceeded 16KB chunk-extension budget");
break;
}
return Err(e.into());
} Prevention
- Keep per-chunk extensions tiny or omit them; put metadata in a single trailer.
- Batch data into fewer chunks to avoid repeating extensions hundreds of times.
- Monitor 'chunk extensions over limit' as a DoS signal on public endpoints.
When it happens
Trigger: A chunked body whose combined extension text (everything after ';' on every chunk-size line, summed over all chunks) reaches 16384 bytes — e.g. many small chunks each carrying a large correlation-id extension, or one chunk with a >16KB extension blob.
Common situations: Tracing/observability proxies that attach large trace-state or baggage to every chunk; a sender that embeds base64 payloads in extensions; abuse/DoS where an attacker stuffs extensions to exhaust memory.
Related errors
- invalid chunk extension contains newline
- chunk trailers count overflow
- Partial header
- Invalid chunk size line: missing size digit
- Invalid chunk size line: Invalid Size
AI-assisted analysis of hyperium/hyper@084473f728 (2026-08-06).
Data as JSON: /data/errors/c07baf441e9fc7fd.json.
Report an issue: GitHub.