actix/actix-web · error · io::Error
Invalid chunk size linear white space
Error message
Invalid chunk size linear white space
What it means
Raised in read_size_lws (chunked.rs:95) when, after consuming linear whitespace (space/tab) following the chunk size, the next byte is not another LWS, a ';' (extension), or CR. RFC 7230 allows optional LWS after the size but nothing else, so any other character is a framing error surfacing as PayloadError::Io / 400.
Solutions
- Ensure chunk-size lines are strictly <hex-size> [ ";ext" ] CRLF with only optional spaces/tabs before the extension or CRLF.
- Use a mature HTTP client library rather than hand-serializing chunked bodies.
- Verify any intermediary proxy preserves chunk framing byte-for-byte.
Example fix
// before "4 x\r\ndata\r\n" // after "4\r\ndata\r\n" // or "4;ext\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(), // bad LWS after chunk size
_ => { /* ... */ }
} Prevention
- Format chunk-size lines as <hex>[;ext]CRLF only.
- Use a vetted HTTP client.
- Check proxy framing behavior.
When it happens
Trigger: A chunk-size line like "4 X\r\n" where a non-LWS character follows the whitespace, or stray bytes after the size digits. The SizeLws state only accepts \t, ' ', ';', '\r'.
Common situations: Client inserting stray characters after the chunk size; corrupt body from a proxy; malformed custom HTTP serializer.
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/792c57f9a91e4e3a.
Report an issue: GitHub.
Appendix: source
Thrown at actix-http/src/h1/chunked.rs:95
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",
)))
}
}
}
fn read_size_lws(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
match byte!(rdr) {
// LWS can follow the chunk size, but no more digits can come
b'\t' | b' ' => Poll::Ready(Ok(ChunkedState::SizeLws)),
b';' => Poll::Ready(Ok(ChunkedState::Extension)),
b'\r' => Poll::Ready(Ok(ChunkedState::SizeLf)),
_ => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk size linear white space",
))),
}
}
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) {View on GitHub (pinned to 4d435abc28)