actix/actix-web · error · io::Error
Invalid chunk end CR
Error message
Invalid chunk end CR
What it means
io::Error(InvalidInput, "Invalid chunk end CR") (chunked.rs:172-175) is returned by read_end_cr after a zero-sized terminating chunk ('0' CRLF) when the next byte is not a CR. The chunked encoding trailer sequence is '0' CRLF *(trailer-field) CRLF; this state expects the final CR that closes the message.
Source
Thrown at actix-http/src/h1/chunked.rs:172
_ => 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(
io::ErrorKind::InvalidInput,
"Invalid chunk end CR",
))),
}
}
fn read_end_lf(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
match byte!(rdr) {
b'\n' => Poll::Ready(Ok(ChunkedState::End)),
_ => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk end LF",
))),
}
}
}
#[cfg(test)]
mod tests {View on GitHub (pinned to 937960ca67)
Solutions
- Ensure the chunked body ends with '0\r\n\r\n' (last-chunk plus empty trailer line).
- Check that the client is not closing the connection before flushing the trailer.
- Verify intermediaries pass the trailer through unchanged.
Example fix
// before: missing final terminator b"4\r\ndata\r\n0\r\n" // after: complete trailer b"4\r\ndata\r\n0\r\n\r\n"
Defensive patterns
Strategy: try-catch
Try / catch
// Missing final trailer CR -> bad request / incomplete body.
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
- Ensure chunked bodies end with '0\r\n\r\n'.
- Confirm the client flushes the trailer before closing the socket.
- Check proxies forward trailers unchanged.
When it happens
Trigger: After the '0\r\n' last-chunk, the peer sends something other than CR to begin the final empty line, e.g. '0\r\nX'. read_size_lf transitioned to EndCr (size==0) and read_end_cr sees 'X'.
Common situations: A chunked body that omits the final CRLF terminator, or a proxy truncating the stream before the trailer.
Related errors
- Invalid chunk size line: Invalid Size
- Invalid chunk size linear white space
- Invalid chunk size LF
- Invalid chunk body CR
- Invalid chunk body LF
AI-assisted analysis of actix/actix-web@937960ca67 (2026-08-06).
Data as JSON: /data/errors/ec4ac6a50c92c701.json.
Report an issue: GitHub.