hyperium/hyper · error · std::io::Error
Invalid chunk size LF
Error message
Invalid chunk size LF
What it means
Thrown in read_size_lf (src/proto/h1/decode.rs:469) after the decoder saw '\r' ending the chunk-size line and expects the following '\n'. Any byte other than '\n' yields io::ErrorKind::InvalidInput, meaning the size line's CRLF terminator was malformed (a CR not followed by LF).
Source
Thrown at src/proto/h1/decode.rs:469
} // no supported extensions
}
}
fn read_size_lf<R: MemRead>(
cx: &mut Context<'_>,
rdr: &mut R,
size: u64,
) -> Poll<Result<ChunkedState, io::Error>> {
trace!("Chunk size is {:?}", size);
match byte!(rdr, cx) {
b'\n' => {
if size == 0 {
Poll::Ready(Ok(ChunkedState::EndCr))
} else {
debug!("incoming chunked header: {0:#X} ({0} bytes)", size);
Poll::Ready(Ok(ChunkedState::Body))
}
}
_ => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk size LF",
))),
}
}
fn read_body<R: MemRead>(
cx: &mut Context<'_>,
rdr: &mut R,
rem: &mut u64,
buf: &mut Option<Bytes>,
) -> Poll<Result<ChunkedState, io::Error>> {
trace!("Chunked read, remaining={:?}", rem);
// cap remaining bytes at the max capacity of usize
let to_read = usize::try_from(*rem).unwrap_or(usize::MAX);
let slice = ready!(rdr.read_mem(cx, to_read))?;
let count = slice.len();View on GitHub (pinned to 084473f728)
Solutions
- Confirm the size line is terminated by a true CRLF (\r\n), not a lone CR.
- Audit any middleware that transforms newlines in the response body.
- Re-emit framing with write!(w, "{:x}\r\n", len) so both bytes are always written.
Example fix
// before: only CR written
write!(w, "{:x}\r", len).await?; // -> error 25
// after: full CRLF
write!(w, "{:x}\r\n", len).await?; Defensive patterns
Strategy: try-catch
Try / catch
Some(Err(e)) => {
let kind = e.source()
.and_then(|s| s.downcast_ref::<std::io::Error>())
.map(|io| io.kind());
if matches!(kind, Some(std::io::ErrorKind::InvalidInput)) {
tracing::warn!(error=%e, "chunk size line CR not followed by LF");
break;
}
return Err(e.into());
} Prevention
- Always write the size-line terminator as the literal "\r\n", never a lone "\r".
- Disable body newline transcoding in upstream proxies.
- Write framing bytes from a single buffer to avoid splitting CR from LF across writes.
When it happens
Trigger: A chunk-size line ending in CR but not LF, e.g. "F\rF" (CR followed by 'F'), or a sender that writes "\r" alone and then data with no LF.
Common situations: A peer or middleware that strips/converts LF; a transport that drops the LF byte; copy-paste of chunk examples that used a bare CR.
Related errors
- Invalid chunk size line: missing size digit
- Invalid chunk size line: Invalid Size
- Invalid chunk size linear white space
- Invalid chunk body CR
- Invalid chunk body LF
AI-assisted analysis of hyperium/hyper@084473f728 (2026-08-06).
Data as JSON: /data/errors/a04d8940d04be671.json.
Report an issue: GitHub.