actix/actix-web · error · io::Error
Invalid chunk body CR
Error message
Invalid chunk body CR
What it means
Raised in read_body_cr (chunked.rs:154) when the byte immediately following a chunk's body data is not CR. RFC 7230 requires every non-terminal chunk to be followed by CRLF; this state reads the CR after exactly 'size' body bytes and rejects anything else.
Solutions
- Ensure each chunk's declared hex size exactly equals the number of body bytes that follow before the CRLF.
- Use a vetted HTTP client library to produce chunked bodies.
- Validate/normalize chunked framing at any proxy boundary.
Example fix
// before "5\r\nabcdX\r\n" // size says 5 but body mismatch // after "4\r\nabcd\r\n" // size matches body length
Defensive patterns
Strategy: try-catch
Try / catch
match payload.next().await {
Some(Err(PayloadError::Io(e))) if e.kind() == io::ErrorKind::InvalidInput =>
return HttpResponse::BadRequest().finish(), // chunk body CR missing
_ => { /* ... */ }
} Prevention
- Make declared chunk sizes exactly match the following body byte count.
- Always append CRLF after each chunk body.
- Use a mature HTTP serializer.
When it happens
Trigger: The declared chunk size doesn't match the actual data length, so after consuming 'size' bytes the parser finds a non-CR byte. e.g. declaring "5\r\n" but only sending 4 data bytes before other content.
Common situations: Client mis-counting chunk payload length; truncated/injected bytes mid-stream; proxy re-chunking incorrectly; smuggling attempt with mismatched sizes.
Related errors
- Invalid chunk body LF
- Invalid chunk end CR
- Invalid chunk end LF
- Invalid chunk size LF
- Invalid chunk size line: Invalid Size
AI-assisted analysis of actix/actix-web@4d435abc28 (2026-08-09).
Data as JSON: /api/errors/de359ad1015d0650.
Report an issue: GitHub.
Appendix: 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 4d435abc28)