actix/actix-web · error · io::Error
Invalid chunk size line: Invalid Size
Error message
Invalid chunk size line: Invalid Size
What it means
Raised in ChunkedState::read_size (chunked.rs:65) when the first byte of a chunk-size field is not a hex digit and not one of the allowed delimiters (space/tab, ';', or CR). It signals a structurally invalid chunked transfer-encoding body and surfaces upstream as a PayloadError::Io, typically causing a 400 Bad Request when reading the request body.
Solutions
- Ensure the client emits chunk sizes as lowercase/uppercase hexadecimal followed by CRLF.
- If behind a reverse proxy, make proxy and backend agree: either the proxy fully de-chunks and sends Content-Length, or it forwards valid chunked framing.
- Handle the resulting PayloadError and respond 400 rather than 500.
Example fix
// before (client body) "G\r\nhello\r\n0\r\n\r\n" // after "5\r\nhello\r\n0\r\n\r\n"
Defensive patterns
Strategy: try-catch
Try / catch
// Errors surface while reading the body payload
while let Some(res) = payload.next().await {
match res {
Ok(chunk) => { /* process */ }
Err(PayloadError::Io(e)) if e.kind() == io::ErrorKind::InvalidInput =>
return HttpResponse::BadRequest().finish(),
Err(e) => return Err(e.into()),
}
} Prevention
- Use a compliant HTTP client for chunked requests.
- Don't hand-roll chunked framing.
- Ensure proxies either forward valid chunked bodies or fully de-chunk them.
When it happens
Trigger: A chunked request body begins a chunk-size line with a non-hex character, e.g. the body sent "G\r\n..." or "x4\r\ndata\r\n". The byte! macro reads one byte and the wildcard arm at chunked.rs:64 fires.
Common situations: A buggy HTTP client not emitting hex chunk sizes; a request smuggling attempt; a proxy that strips or corrupts the chunked encoding; misconfigured reverse proxy forwarding a de-chunked body but leaving Transfer-Encoding: chunked.
Related errors
- Invalid chunk body CR
- Invalid chunk body LF
- Invalid chunk end CR
- Invalid chunk end LF
- Invalid chunk size LF
AI-assisted analysis of actix/actix-web@4d435abc28 (2026-08-09).
Data as JSON: /api/errors/54f609f9dcd01e72.
Report an issue: GitHub.
Appendix: 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 4d435abc28)