actix/actix-web · error · io::Error
Invalid chunk size LF
Error message
Invalid chunk size LF
What it means
Raised in read_size_lf (chunked.rs:116) when the byte expected to be the LF terminating the chunk-size line is not '\n'. After read_size/read_size_lws/read_extension consume the CR, this state requires a single '\n'; anything else is a malformed CRLF terminator.
Solutions
- Always terminate chunk-size lines with a full CRLF (\r\n) as required by RFC 7230.
- Use a standards-compliant HTTP client library to serialize chunked requests.
- Check intermediary proxies for CRLF normalization bugs.
Example fix
// before "4\rdata\r\n" // after "4\r\ndata\r\n"
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 size LF missing
_ => { /* ... */ }
} Prevention
- Terminate every chunk-size line with CRLF (\r\n).
- Use a compliant client library.
- Audit proxies for CRLF normalization.
When it happens
Trigger: A chunk-size line terminates with CR followed by a non-LF byte, e.g. "4\rX\r\n" or a lone CR without LF. The state machine enters SizeLf expecting '\n' and gets something else.
Common situations: Client using bare LF (\n) line endings inconsistently so the parser sees CR then a digit; corrupt/truncated body; proxy mangling CRLF.
Related errors
- Invalid chunk body CR
- Invalid chunk body LF
- Invalid chunk end CR
- Invalid chunk end LF
- Invalid chunk size line: Invalid Size
AI-assisted analysis of actix/actix-web@4d435abc28 (2026-08-09).
Data as JSON: /api/errors/b4f995461c9eedce.
Report an issue: GitHub.
Appendix: source
Thrown at actix-http/src/h1/chunked.rs:116
))),
}
}
fn read_extension(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
match byte!(rdr) {
b'\r' => Poll::Ready(Ok(ChunkedState::SizeLf)),
// strictly 0x20 (space) should be disallowed but we don't parse quoted strings here
0x00..=0x08 | 0x0a..=0x1f | 0x7f => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid character in chunk extension",
))),
_ => Poll::Ready(Ok(ChunkedState::Extension)), // no supported extensions
}
}
fn read_size_lf(rdr: &mut BytesMut, size: u64) -> Poll<Result<ChunkedState, io::Error>> {
match byte!(rdr) {
b'\n' if size > 0 => Poll::Ready(Ok(ChunkedState::Body)),
b'\n' if size == 0 => Poll::Ready(Ok(ChunkedState::EndCr)),
_ => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk size LF",
))),
}
}
fn read_body(
rdr: &mut BytesMut,
rem: &mut u64,
buf: &mut Option<Bytes>,
) -> Poll<Result<ChunkedState, io::Error>> {
trace!("Chunked read, remaining={:?}", rem);
let len = rdr.len() as u64;
if len == 0 {
Poll::Ready(Ok(ChunkedState::Body))
} else {
let slice;View on GitHub (pinned to 4d435abc28)