seanmonstar/warp · error · UnsupportedMediaType

unsupported_media_type

Error message

unsupported_media_type

What it means

warp::body's is_content_type filter rejects the request with an unsupported_media_type (415) rejection when the Content-Type header is present but its MIME type does not match the MIME type expected by the body decoder (D::MIME, e.g. application/json for warp::body::json()). It is a validation helper guarding deserializers: only requests whose parsed Content-Type equals the expected type_/subtype pass.

Solutions

  1. Set the client's Content-Type header to match the expected decoder, e.g. application/json for warp::body::json() or application/x-www-form-urlencoded for form()
  2. Handle the rejection with .recover() and map reject::unsupported_media_type() to a 415 response listing accepted media types
  3. Use the matching body filter for the actual payload format (json(), form(), text(), bytes())
  4. Check for missing charset/parameters issues: the MIME parse only compares type and subtype, so ensure the header itself is a parseable MIME string
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/filters/body.rs:279 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of seanmonstar/warp@ff34d7213e (2026-09-09). Data as JSON: /api/errors/5f85af3e98562765. Report an issue: GitHub.

Appendix: source

Thrown at src/filters/body.rs:279

    filter_fn(move |route| {
        let (type_, subtype) = D::MIME;
        if let Some(value) = route.headers().get(CONTENT_TYPE) {
            tracing::trace!("is_content_type {}/{}? {:?}", type_, subtype, value);
            let ct = value
                .to_str()
                .ok()
                .and_then(|s| s.parse::<mime::Mime>().ok());
            if let Some(ct) = ct {
                if ct.type_() == type_ && ct.subtype() == subtype {
                    future::ok(())
                } else {
                    tracing::debug!(
                        "content-type {:?} doesn't match {}/{}",
                        value,
                        type_,
                        subtype
                    );
                    future::err(reject::unsupported_media_type())
                }
            } else {
                tracing::debug!("content-type {:?} couldn't be parsed", value);
                future::err(reject::unsupported_media_type())
            }
        } else if D::WITH_NO_CONTENT_TYPE {
            // Optimistically assume its correct!
            tracing::trace!("no content-type header, assuming {}/{}", type_, subtype);
            future::ok(())
        } else {
            tracing::debug!("no content-type found");
            future::err(reject::unsupported_media_type())
        }
    })
}

// ===== Rejections =====

View on GitHub (pinned to ff34d7213e)