hyperium/hyper · error · std::io::Error
Invalid trailer end LF
Error message
Invalid trailer end LF
What it means
Thrown in read_trailer_lf (src/proto/h1/decode.rs:578) for a trailer line that began with '\r' (transitioning to TrailerLf) but whose next byte is not '\n'. A trailer header must be terminated by CRLF; a CR not followed by LF yields io::ErrorKind::InvalidInput.
Source
Thrown at src/proto/h1/decode.rs:578
match byte {
b'\n' => {
if *trailers_cnt >= h1_max_headers {
return Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidData,
"chunk trailers count overflow",
)));
}
*trailers_cnt += 1;
put_u8!(
trailers_buf.as_mut().expect("trailers_buf is None"),
byte,
h1_max_header_size
);
Poll::Ready(Ok(ChunkedState::EndCr))
}
_ => Poll::Ready(Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid trailer end LF",
))),
}
}
fn read_end_cr<R: MemRead>(
cx: &mut Context<'_>,
rdr: &mut R,
trailers_buf: &mut Option<BytesMut>,
h1_max_header_size: usize,
) -> Poll<Result<ChunkedState, io::Error>> {
let byte = byte!(rdr, cx);
match byte {
b'\r' => {
if let Some(trailers_buf) = trailers_buf {
put_u8!(trailers_buf, byte, h1_max_header_size);
}View on GitHub (pinned to 084473f728)
Solutions
- Ensure every trailer line ends with a true CRLF (\r\n).
- Validate/normalize newline handling for trailer-encoding middleware.
- Write the trailer block from a single buffer so CR and LF can't be split.
Example fix
// before: trailer written with lone CR write!(w, "0\r\nx-trace: abc\r").await?; // -> error 30 write!(w, "\r\n").await?; // after: each trailer terminated by CRLF, then blank line write!(w, "0\r\nx-trace: abc\r\n\r\n").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, "trailer CR not followed by LF");
break;
}
return Err(e.into());
} Prevention
- Terminate every trailer line with a full CRLF and end the block with a blank CRLF line.
- Build the trailer block in one buffer and write it once, so CR/LF aren't split.
- Check newline handling in any component that rewrites trailers.
When it happens
Trigger: A trailer block like "0\r\nbad\r\r\n" where a trailer line's CR is followed by another CR or other byte instead of LF, or any trailer whose terminator lost its LF.
Common situations: A proxy that mangles newlines in trailers; a custom encoder that writes "\r" only at end of each trailer; corrupted bytes near the end of the body.
Related errors
- Invalid chunk size line: missing size digit
- Invalid chunk size line: Invalid Size
- Invalid chunk size linear white space
- Invalid chunk size LF
- Invalid chunk body CR
AI-assisted analysis of hyperium/hyper@084473f728 (2026-08-06).
Data as JSON: /data/errors/aaecc72085fd8a31.json.
Report an issue: GitHub.