hyperium/hyper · error · std::io::Error

Invalid header name: {:?}

Error message

Invalid header name: {:?}

What it means

Thrown by decode_trailers (src/proto/h1/decode.rs:650) when a parsed trailer header's name fails HeaderName::try_from — i.e. it contains characters not allowed in HTTP field names (only visible VCHAR excluding ':' is permitted). The offending header is included in the message via {:?}. Reported as io::ErrorKind::InvalidInput.

Source

Thrown at src/proto/h1/decode.rs:650

                "Invalid chunk end LF",
            ))),
        }
    }
}

// TODO: disallow Transfer-Encoding, Content-Length, Trailer, etc in trailers ??
fn decode_trailers(buf: &mut BytesMut, count: usize) -> Result<HeaderMap, io::Error> {
    let mut trailers = HeaderMap::new();
    let mut headers = vec![httparse::EMPTY_HEADER; count];
    let res = httparse::parse_headers(buf, &mut headers);
    match res {
        Ok(httparse::Status::Complete((_, headers))) => {
            for header in headers {
                use std::convert::TryFrom;
                let name = match HeaderName::try_from(header.name) {
                    Ok(name) => name,
                    Err(_) => {
                        return Err(io::Error::new(
                            io::ErrorKind::InvalidInput,
                            format!("Invalid header name: {:?}", &header),
                        ));
                    }
                };

                let value = match HeaderValue::from_bytes(header.value) {
                    Ok(value) => value,
                    Err(_) => {
                        return Err(io::Error::new(
                            io::ErrorKind::InvalidInput,
                            format!("Invalid header value: {:?}", &header),
                        ));
                    }
                };

                trailers.append(name, value);
            }

View on GitHub (pinned to 084473f728)

Solutions

  1. Sanitize trailer names on the sending side: ASCII tokens, no spaces, no colon, typically lower-case kebab.
  2. Reject/redirect upstream metadata that isn't a valid HTTP field name instead of forwarding it as a trailer.
  3. Log the offending header (it appears in the error) to identify which peer/component produced it.

Example fix

// before: forwarding arbitrary metadata as a trailer
let name = format!("{}", raw_key); // may contain spaces/unicode
write!(w, "0\r\n{}: {}\r\n\r\n", name, val).await?; // -> error 32

// after: validate/sanitize the field name
fn trailer_name(raw: &str) -> Option<&str> {
    let r = raw.as_bytes();
    r.iter().all(|b| b.is_ascii_alphanumeric() || matches!(b, b'-' | b'_'))
        .then_some(raw)
}
if let Some(n) = trailer_name(&raw_key) {
    write!(w, "0\r\n{}: {}\r\n\r\n", n, val).await?;
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate trailer names before emitting them: HTTP token chars only.
fn valid_trailer_name(name: &str) -> bool {
    !name.is_empty() && name.as_bytes().iter().all(|b| {
        matches!(b,
            b'!' | b'#' | b'$' | b'%' | b'&' | b'\'' | b'*' | b'+'
            | b'-' | b'.' | b'^' | b'_' | b'`' | b'|' | b'~'
            | b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z')
    })
}
if valid_trailer_name(&key) {
    write!(w, "0\r\n{}: {}\r\n\r\n", key, val).await?;
}

Type guard

fn valid_trailer_name(name: &str) -> bool {
    !name.is_empty() && name.as_bytes().iter().all(|b| {
        matches!(b,
            b'!' | b'#'..=b'\'' | b'*' | b'+' | b'-' | b'.' | b'^'..=b'`' | b'|' | b'~'
            | b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z')
    })
}

Try / catch

Some(Err(e)) => {
    if e.to_string().contains("Invalid header name") {
        tracing::warn!(error=%e, "peer sent trailer with illegal field name");
        break;
    }
    return Err(e.into());
}

Prevention

When it happens

Trigger: A trailer block whose header name is illegal, e.g. "X Bad: 1\r\n" (space in name), "X-Trace\r\n" (no colon treated as invalid by httparse and surfaced here), or a non-ASCII field name like a UTF-8 label.

Common situations: A proxy injecting malformed trailer names; UTF-8 metadata from an upstream system placed verbatim into trailers; gRPC metadata keys that violate HTTP token rules (e.g. uppercase or spaces).

Related errors


AI-assisted analysis of hyperium/hyper@084473f728 (2026-08-06). Data as JSON: /data/errors/c75548b51a89a801.json. Report an issue: GitHub.