hyperium/hyper · error · std::io::Error
Invalid chunk body CR
Error message
Invalid chunk body CR
What it means
Thrown in read_body_cr (src/proto/h1/decode.rs:511) after reading exactly chunk_len bytes of chunk data: the next byte must be '\r' (start of the trailing CRLF). Any other byte yields io::ErrorKind::InvalidInput, meaning the chunk's data ran long or short relative to its announced size.
Source
Thrown at src/proto/h1/decode.rs:511
IncompleteBody,
)));
}
*buf = Some(slice);
*rem -= count as u64;
if *rem > 0 {
Poll::Ready(Ok(ChunkedState::Body))
} else {
Poll::Ready(Ok(ChunkedState::BodyCr))
}
}
fn read_body_cr<R: MemRead>(
cx: &mut Context<'_>,
rdr: &mut R,
) -> Poll<Result<ChunkedState, io::Error>> {
match byte!(rdr, cx) {
b'\r' => Poll::Ready(Ok(ChunkedState::BodyLf)),
_ => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk body CR",
))),
}
}
fn read_body_lf<R: MemRead>(
cx: &mut Context<'_>,
rdr: &mut R,
) -> Poll<Result<ChunkedState, io::Error>> {
match byte!(rdr, cx) {
b'\n' => Poll::Ready(Ok(ChunkedState::Start)),
_ => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk body LF",
))),
}
}
View on GitHub (pinned to 084473f728)
Solutions
- Verify the announced hex size equals the exact number of data bytes before the CRLF.
- If you compress, chunk after compression (or recompute the length) so counts stay consistent.
- Serialize/stream body writes from a single task so sizes and data can't drift apart.
Example fix
// before: announcing a fixed size then streaming variable data
write!(w, "10\r\n").await?;
w.write_all(&maybe_seventeen_bytes).await?; // -> error 27
write!(w, "\r\n").await?;
// after: announce the real length
write!(w, "{:x}\r\n", data.len()).await?;
w.write_all(&data).await?;
write!(w, "\r\n").await?; Defensive patterns
Strategy: try-catch
Try / catch
Some(Err(e)) => {
let kind = e.source()
.and_then(|s| s.downcast_ref::<std::io::Error>())
.map(|io| io.kind());
if matches!(kind, Some(std::io::ErrorKind::InvalidInput)) {
tracing::warn!(error=%e, "chunk body not followed by CRLF (size/data mismatch)");
break;
}
return Err(e.into());
} Prevention
- Compute the chunk length from the exact bytes you write: write!("{:x}\r\n", data.len()).
- Apply compression before chunking (or recompute size) so counts don't drift.
- Serialize body writes from one task to avoid interleaving size/data from different producers.
When it happens
Trigger: A chunk that announced "10\r\n" (16 bytes) but whose 17th byte is not '\r' — e.g. "10\r\n1234567890abcdefX\r\n" — because the sender wrote 17 bytes, or miscounted and the CRLF landed at the wrong offset.
Common situations: Off-by-one in a custom chunker; concurrent writes to the body stream that interleave data of different lengths than announced; compression applied after chunking so byte counts drift.
Related errors
- Invalid chunk size line: missing size digit
- Invalid chunk size line: Invalid Size
- Invalid chunk size linear white space
- Invalid chunk size LF
- Invalid chunk body LF
AI-assisted analysis of hyperium/hyper@084473f728 (2026-08-06).
Data as JSON: /data/errors/74121a45846e47da.json.
Report an issue: GitHub.