actix/actix-web · error · io::Error
Invalid chunk size line: Invalid Size
Error message
Invalid chunk size line: Invalid Size
What it means
io::Error(InvalidInput, "Invalid chunk size line: Invalid Size") (chunked.rs:65-68) is returned by ChunkedState::read_size when the first byte of a chunk size field is not a hex digit, whitespace, ';', or CR. It aborts decoding of a Transfer-Encoding: chunked HTTP/1.1 body whose framing is malformed, surfacing as PayloadError::Io to the request/response reader.
Source
Thrown at actix-http/src/h1/chunked.rs:65
BodyLf => ChunkedState::read_body_lf(body),
EndCr => ChunkedState::read_end_cr(body),
EndLf => ChunkedState::read_end_lf(body),
End => Poll::Ready(Ok(ChunkedState::End)),
}
}
fn read_size(rdr: &mut BytesMut, size: &mut u64) -> Poll<Result<ChunkedState, io::Error>> {
let radix = 16;
let rem = match byte!(rdr) {
b @ b'0'..=b'9' => b - b'0',
b @ b'a'..=b'f' => b + 10 - b'a',
b @ b'A'..=b'F' => 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",
)));
}
};
match size.checked_mul(radix) {
Some(n) => {
*size = n;
*size += rem as u64;
Poll::Ready(Ok(ChunkedState::Size))
}
None => {
debug!("chunk size would overflow u64");
Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk size line: Size is too big",View on GitHub (pinned to 937960ca67)
Solutions
- Fix the peer to emit valid hex chunk sizes terminated by CRLF.
- If you do not need chunked encoding, send a Content-Length instead.
- Capture the raw bytes on the wire to locate the malformed line.
Example fix
// before: non-hex chunk size b"G\r\ndata\r\n0\r\n\r\n" // after: valid hex size b"4\r\ndata\r\n0\r\n\r\n"
Defensive patterns
Strategy: try-catch
Try / catch
// PayloadError surfaces when reading the request/response body.
use actix_http::error::PayloadError;
match body.next().await {
Some(Err(PayloadError::Io(e))) if e.kind() == io::ErrorKind::InvalidInput => {
// malformed chunked framing; reject the request as 400
return HttpResponse::BadRequest().finish();
}
Some(other) => { /* ... */ }
None => { /* done */ }
} Prevention
- Use a well-tested HTTP client/server library that emits correct chunked framing.
- Prefer Content-Length for fixed-size bodies.
- Reject malformed Transfer-Encoding at the edge (reverse proxy).
When it happens
Trigger: A chunked HTTP/1.1 request or response begins a chunk-size line with an illegal character, e.g. 'G\r\n' instead of a hex size. The state machine in chunked.rs:54-69 hits the default arm.
Common situations: A buggy client/server hand-rolling chunked encoding, a proxy corrupting the stream, or a fuzzer probing the parser. Browsers and curl never produce this.
Related errors
- Invalid chunk size linear white space
- Invalid chunk size LF
- Invalid chunk body CR
- Invalid chunk body LF
- Invalid chunk end CR
AI-assisted analysis of actix/actix-web@937960ca67 (2026-08-06).
Data as JSON: /data/errors/54f609f9dcd01e72.json.
Report an issue: GitHub.