actix/actix-web · error · io::Error
Invalid chunk body CR
Error message
Invalid chunk body CR
What it means
io::Error(InvalidInput, "Invalid chunk body CR") (chunked.rs:154-157) is returned by read_body_cr when, after consuming exactly <size> body bytes, the next byte is not a CR. RFC 7230 requires each chunk body be terminated by CRLF; any other byte here is a framing error.
Source
Thrown at actix-http/src/h1/chunked.rs:154
slice = rdr.split().freeze();
*rem -= len;
} else {
slice = rdr.split_to(*rem as usize).freeze();
*rem = 0;
}
*buf = Some(slice);
if *rem > 0 {
Poll::Ready(Ok(ChunkedState::Body))
} else {
Poll::Ready(Ok(ChunkedState::BodyCr))
}
}
}
fn read_body_cr(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
match byte!(rdr) {
b'\r' => Poll::Ready(Ok(ChunkedState::BodyLf)),
_ => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk body CR",
))),
}
}
fn read_body_lf(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
match byte!(rdr) {
b'\n' => Poll::Ready(Ok(ChunkedState::Size)),
_ => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk body LF",
))),
}
}
fn read_end_cr(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
match byte!(rdr) {
b'\r' => Poll::Ready(Ok(ChunkedState::EndLf)),
_ => Poll::Ready(Err(io::Error::new(View on GitHub (pinned to 937960ca67)
Solutions
- Make the peer's declared chunk size exactly equal the number of body bytes that follow.
- Verify no intermediary is re-segmenting the body.
- Switch to Content-Length if the full size is known up front.
Defensive patterns
Strategy: try-catch
Try / catch
// Mismatched chunk length -> bad request.
use actix_http::error::PayloadError;
if matches!(payload.next().await, Some(Err(PayloadError::Io(e))) if e.kind() == io::ErrorKind::InvalidInput) {
return HttpResponse::BadRequest().finish();
} Prevention
- Make the declared chunk size exactly equal the number of body bytes that follow.
- Avoid re-chunking the body in intermediaries.
- Prefer Content-Length for fixed-size payloads.
When it happens
Trigger: The declared chunk size does not match the actual body length, so the parser reads the 'wrong' bytes as the terminator. e.g. declaring '4' but sending only 3 data bytes leaves the 4th data byte to be checked against CR.
Common situations: Encoder miscalculating chunk length, a proxy truncating or re-chunking the body, or a client streaming an incorrect size.
Related errors
- Invalid chunk size line: Invalid Size
- Invalid chunk size linear white space
- Invalid chunk size LF
- Invalid chunk body LF
- Invalid chunk end CR
AI-assisted analysis of actix/actix-web@937960ca67 (2026-08-06).
Data as JSON: /data/errors/de359ad1015d0650.json.
Report an issue: GitHub.