hyperium/hyper · error · hyper::Error

error reading a body from connection

Error message

error reading a body from connection

What it means

Thrown via Error::new_body() (src/error.rs:406, Kind::Body). It means reading the message body from the connection failed — an IO or framing error occurred while streaming body bytes. The concrete cause is attached via .with(cause). Notable producer: proto/h1/dispatch.rs:132 sends new_body("connection error") into the body when the connection errors during body streaming, and dispatch.rs:280 forwards body errors.

Source

Thrown at src/error.rs:406

    ))]
    pub(super) fn new_io(cause: std::io::Error) -> Error {
        Error::new(Kind::Io).with(cause)
    }

    #[cfg(any(
        all(feature = "http1", any(feature = "client", feature = "server")),
        all(feature = "http2", feature = "client")
    ))]
    pub(super) fn new_closed() -> Error {
        Error::new(Kind::ChannelClosed)
    }

    #[cfg(all(
        any(feature = "client", feature = "server"),
        any(feature = "http1", feature = "http2")
    ))]
    pub(super) fn new_body<E: Into<Cause>>(cause: E) -> Error {
        Error::new(Kind::Body).with(cause)
    }

    #[cfg(all(
        any(feature = "client", feature = "server"),
        any(feature = "http1", feature = "http2")
    ))]
    pub(super) fn new_body_write<E: Into<Cause>>(cause: E) -> Error {
        Error::new(Kind::BodyWrite).with(cause)
    }

    #[cfg(any(
        all(feature = "http1", any(feature = "client", feature = "server")),
        feature = "ffi"
    ))]
    pub(super) fn new_body_write_aborted() -> Error {
        Error::new(Kind::User(User::BodyWriteAborted))
    }

View on GitHub (pinned to 084473f728)

Solutions

  1. Inspect Error::source() for the underlying io::Error or h2::Error to distinguish truncation from a hard network failure.
  2. For idempotent requests, retry the whole request on a new connection (partial bodies must be discarded).
  3. If you are a server, log the request id and 4xx/5xx appropriately; ensure clients send accurate Content-Length or well-formed chunked bodies.

Example fix

// before: read whole body, any failure is fatal
let bytes = hyper::body::to_bytes(resp.into_body()).await?;

// after: surface truncation distinctly and retry idempotent fetches
async fn read_all(client: &Client<...>, uri: Uri) -> Result<Bytes, hyper::Error> {
    for attempt in 0..2u8 {
        let resp = client.get(uri.clone()).await?;
        match hyper::body::to_bytes(resp.into_body()).await {
            Ok(b) => return Ok(b),
            Err(e) if attempt == 0 => continue, // body read failed, retry
            Err(e) => return Err(e),
        }
    }
    unreachable!()
}
Defensive patterns

Strategy: retry

Type guard

fn is_body_read_error(err: &hyper::Error) -> bool {
    // hyper doesn't expose a dedicated predicate for Kind::Body; classify via source.
    err.source().and_then(|s| s.downcast_ref::<std::io::Error>()).is_some()
}

Try / catch

for attempt in 0..2u8 {
    let resp = client.get(uri.clone()).await?;
    match hyper::body::to_bytes(resp.into_body()).await {
        Ok(b) => return Ok(b),
        Err(e) if attempt == 0 && idempotent => continue,
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: The socket returns an error (EOF/RST) partway through reading a chunked or Content-Length body; the dispatch loop detects a connection error while a body frame is outstanding (dispatch.rs:132); an HTTP/2 body stream errors (DATA frame / stream error). The reader of hyper::body sees it as a body read failure.

Common situations: Upstream cuts the body short (length mismatch / premature close); a proxy times out and drops the body; network glitch mid-download; chunked encoding truncated; a server that closes before sending the promised Content-Length bytes.

Related errors


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