hyperium/hyper · error · std::io::Error
Invalid chunk size line: Invalid Size
Error message
Invalid chunk size line: Invalid Size
What it means
Thrown in the Size state (src/proto/h1/decode.rs:399) while consuming subsequent bytes of the chunk-size token. Only hex digits, linear whitespace (tab/space), ';' (start of an extension), or '\r' (end of the size line) are accepted; any other byte is reported as io::ErrorKind::InvalidInput. It means the size token contained an illegal character after a valid leading hex digit.
Source
Thrown at src/proto/h1/decode.rs:399
let radix = 16;
match byte!(rdr, cx) {
b @ b'0'..=b'9' => {
*size = or_overflow!(size.checked_mul(radix));
*size = or_overflow!(size.checked_add(u64::from(b - b'0')));
}
b @ b'a'..=b'f' => {
*size = or_overflow!(size.checked_mul(radix));
*size = or_overflow!(size.checked_add(u64::from(b + 10 - b'a')));
}
b @ b'A'..=b'F' => {
*size = or_overflow!(size.checked_mul(radix));
*size = or_overflow!(size.checked_add(u64::from(b + 10 - b'A')));
}
b'\t' | b' ' => return Poll::Ready(Ok(ChunkedState::SizeLws)),
b';' => return Poll::Ready(Ok(ChunkedState::Extension)),
b'\r' => return Poll::Ready(Ok(ChunkedState::SizeLf)),
_ => {
return Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk size line: Invalid Size",
)));
}
}
Poll::Ready(Ok(ChunkedState::Size))
}
fn read_size_lws<R: MemRead>(
cx: &mut Context<'_>,
rdr: &mut R,
) -> Poll<Result<ChunkedState, io::Error>> {
trace!("read_size_lws");
match byte!(rdr, cx) {
// LWS can follow the chunk size, but no more digits can come
b'\t' | b' ' => Poll::Ready(Ok(ChunkedState::SizeLws)),
b';' => Poll::Ready(Ok(ChunkedState::Extension)),
b'\r' => Poll::Ready(Ok(ChunkedState::SizeLf)),
_ => Poll::Ready(Err(io::Error::new(View on GitHub (pinned to 084473f728)
Solutions
- Inspect the exact bytes of the failing chunk-size line and locate the non-hex character.
- Ensure the sender emits only hex digits followed by optional LWS/extension and CRLF ("{:x}\r\n").
- Remove any middleware that decorates the size line with units, comments, or spaces before the CRLF.
Example fix
// before: decimal size with unit suffix
write!(w, "{} bytes\r\n", len).await?; // 'bytes' -> error 21
// after: lowercase hex, no suffix
write!(w, "{:x}\r\n", len).await?; Defensive patterns
Strategy: try-catch
Try / catch
match body.data().await {
Some(Ok(b)) => { /* process */ }
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, "invalid chunk size token; aborting body");
return Ok(None);
}
return Err(e.into());
}
None => {}
} Prevention
- Format chunk sizes with "{:x}"; never append units, spaces-with-text, or comments.
- If you log chunk metadata, write it to a trailer or stderr — not into the size line.
- Fuzz-test your chunk encoder against hyper's decoder.
When it happens
Trigger: A chunk-size line like "1X\r\n", "1 invalid extension\r\n", or "1 A\r\n" where a non-hex, non-terminator byte appears inside the size field. Also triggered by decimal sizes ("10\r\n" is fine because 1 and 0 are hex, but something like "1g\r\n" is not).
Common situations: A sender that writes the chunk length in decimal but appends a unit suffix ("16 bytes\r\n"); a debug logger or middleware that injects text into the size line; a peer that confuses chunk size with Content-Length formatting.
Related errors
- Invalid chunk size line: missing size digit
- Invalid chunk size linear white space
- Invalid chunk size LF
- Invalid chunk body CR
- Invalid chunk body LF
AI-assisted analysis of hyperium/hyper@084473f728 (2026-08-06).
Data as JSON: /data/errors/8ce8c13fb0a92586.json.
Report an issue: GitHub.