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
- 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()
- Handle the rejection with .recover() and map reject::unsupported_media_type() to a 415 response listing accepted media types
- Use the matching body filter for the actual payload format (json(), form(), text(), bytes())
- 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)