HTTP 415 Unsupported Media Type

Unsupported Media Type

HTTP 415 is Unsupported Media Type: the server refuses the request because its content is in a format this method doesn’t support on this resource (RFC 9110 section 15.5.16). The problem can be the request’s Content-Type, its Content-Encoding, or what the server found when it looked at the data itself.

The usual cause: a missing Content-Type

// Sent as Content-Type: text/plain;charset=UTF-8, which a JSON-only endpoint refuses
await fetch('/api/orders', { method: 'POST', body: JSON.stringify(order) });

// Says what it is
await fetch('/api/orders', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(order),
});

fetch() labels a string body text/plain;charset=UTF-8 unless you say otherwise. curl’s -d labels it application/x-www-form-urlencoded; --json (curl 7.82 and later) sends Content-Type: application/json for you.

Tell the client what works

RFC 9110 suggests answering an unsupported media type with an Accept header listing the types that would have worked, and an unsupported content coding with Accept-Encoding. For PATCH, RFC 5789 asks for Accept-Patch:

HTTP/1.1 415 Unsupported Media Type
Accept-Patch: application/merge-patch+json, application/json-patch+json
Content-Type: application/problem+json

{"title": "Unsupported patch format", "status": 415}

415, 406 or 400

Content-Type: application/xml, the server only reads JSON        415 Unsupported Media Type
Accept: application/xml, the server only writes JSON             406 Not Acceptable
Content-Type: application/json, but the body doesn't parse       400 Bad Request

Who sends it

  • Spring MVC answers 415 (HttpMediaTypeNotSupportedException) when no converter can read the request’s Content-Type, or it doesn’t match consumes.
  • ASP.NET Core answers 415 when no input formatter accepts the Content-Type of a [FromBody] parameter, or it fails a [Consumes] filter.
  • Express’s express.json() doesn’t send 415 for a wrong type: it skips the body, leaving req.body empty (undefined in Express 5, {} in Express 4). It sends 415 only for an unsupported charset or Content-Encoding. Check the type yourself:
app.post('/api/orders', (req, res, next) => {
  if (!req.is('application/json')) return res.status(415).set('Accept', 'application/json').end();
  next();
}, express.json(), createOrder);

Gotchas

  • Parameters count. application/json; charset=utf-8 is JSON; compare the media type, not the whole header string. req.is() handles that.
  • Compressed uploads. A server that doesn’t decode compressed request bodies can refuse Content-Encoding: gzip with 415; RFC 9110 says to list the codings it does take in Accept-Encoding.
  • Caching. 415 isn’t heuristically cacheable.

Search 406 415 in the tool below to compare the two.

Try it in the HTTP Status Codes

415 Unsupported Media Type

  1. 415Unsupported Media Type4xx Client error

    The Content-Type of the request is not one this endpoint handles.

    When to use it

    An endpoint that takes JSON being sent XML, or an upload in a format the app cannot read.

    Common mistakes

    Confusing it with 406, which is about what the server sends back rather than what the client sent.

    Not cacheable by defaultRFC 9110

Every code, by class

Codes marked unofficial come from one server’s own convention — nginx, Cloudflare, cPanel, Microsoft — and are not in the IANA registry.

Runs in your browser. Nothing you enter is sent anywhere.