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
- If the abort was intentional, this is expected — ensure the peer can tolerate a truncated body or send a proper error status before aborting.
- If unexpected, audit the handler/body-producer for early returns, panics, or dropped senders.
- 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
- Avoid early returns/panics inside handlers that have already started streaming a body.
- Send a proper error status before aborting if you must stop a response.
- Keep FFI callbacks and body producers from aborting except on explicit user intent.
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
- error writing a body to connection
- channel closed
- error reading a body from connection
- end of file before message length reached
- unexpected EOF during chunk size line
AI-assisted analysis of hyperium/hyper@084473f728 (2026-08-06).
Data as JSON: /data/errors/ebb16fc560eb6e82.json.
Report an issue: GitHub.