hyperium/hyper · error · hyper::Error

user body write aborted

Error message

user body write aborted

What it means

Thrown via Error::new_body_write_aborted() (src/error.rs:422, Kind::User(User::BodyWriteAborted)). It means the outgoing body write was explicitly aborted before completion — hyper's internal state machine detected the user side gave up on writing the response/request body. Detect with Error::is_body_write_aborted(). Produced at proto/h1/conn.rs:808 with the parser 'not_eof' note, and via body/incoming.rs:438 send_error.

Source

Thrown at src/error.rs:422

    ))]
    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))
    }

    fn new_user(user: User) -> Error {
        Error::new(Kind::User(user))
    }

    #[cfg(any(feature = "http1", feature = "http2"))]
    #[cfg(feature = "server")]
    pub(super) fn new_user_header() -> Error {
        Error::new_user(User::UnexpectedHeader)
    }

    #[cfg(all(feature = "http1", feature = "server"))]
    pub(super) fn new_header_timeout() -> Error {
        Error::new(Kind::HeaderTimeout)
    }

    #[cfg(feature = "http1")]

View on GitHub (pinned to 084473f728)

Solutions

  1. If the abort was intentional, this is expected — ensure the peer can tolerate a truncated body or send a proper error status before aborting.
  2. If unexpected, audit the handler/body-producer for early returns, panics, or dropped senders.
  3. Guard body producers so they complete normally (send trailing data / close cleanly) unless you deliberately abort.

Example fix

// before: handler returns early, aborting the response body mid-stream
async fn handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    if !authorized(&req) {
        return Ok(Response::builder().status(403).body(Body::empty()).unwrap());
        // any previously started streaming body is aborted
    }
    /* ... */
}

// after: decide before starting the stream, or complete it cleanly
async fn handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    if !authorized(&req) {
        return Ok(Response::builder().status(403).body(Body::empty()).unwrap());
    }
    Ok(Response::new(stream_body().await))
}
Defensive patterns

Strategy: try-catch

Type guard

fn is_body_write_aborted(err: &hyper::Error) -> bool {
    err.is_body_write_aborted()
}

Try / catch

if let Err(e) = serve_connection(...).await {
    if e.is_body_write_aborted() {
        tracing::warn!("response body was aborted before completion");
    } else {
        return Err(e);
    }
}

Prevention

When it happens

Trigger: A Server drops the Body sender / returns an error that aborts the in-progress response body (conn.rs:808 attaches the not_eof cause); the body channel's send_error is called with this error (incoming.rs:438); an FFI/aborted callback cancels the write. The peer then sees a truncated body.

Common situations: A handler panics or returns early while streaming a response; a service intentionally aborts a response (e.g. after deciding to send an error); an FFI user callback aborted the operation; the body producer was dropped mid-stream.

Related errors


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