Views: 91

415 Unsupported Media Type: Fix the Content-Type

415 Unsupported Media Type means the server rejects your body's Content-Type. Tell it from 400, 406, and 422, then fix it. Free instant check, no sign-up.

Check your domain for this issue now

Free, no sign-up. Runs the exact check this guide describes and shows what to fix.

Problem

A request comes back 415 Unsupported Media Type. The endpoint exists, your auth is fine, and the body you sent looks correct. The server is refusing before it even reads the payload, because the Content-Type you declared isn’t one it will accept on this route.

Symptoms

  • A POST, PUT, or PATCH returns 415 while GET on the same URL returns 200.
  • The exact same JSON works from Postman but fails from curl -d or a hand-rolled fetch.
  • The request started failing after you added gzip compression to the request body.
  • A framework log says something like “no acceptable representation” or “Content-Type ‘text/plain’ not supported.”

What 415 Actually Means

RFC 9110 (§15.5.16) defines 415 as the origin server “refusing to service the request because the content is in a format not supported by this method on the target resource.” Read that carefully: it’s not about your data being wrong, it’s about the format declaration of your data. The server looked at your Content-Type header (and sometimes Content-Encoding), decided it can’t handle that media type here, and stopped.

This is a request-side error, and that’s the single most useful fact about it. A 406 Not Acceptable is the mirror image — that’s the server saying it can’t produce a response matching your Accept header. A 400 means your body is malformed. A 422 means your body parsed fine but failed validation. 415 is none of those. The body was never the problem; the label on the envelope was. Once you internalize that the server rejected you at the type-negotiation step, you stop debugging your JSON and start debugging your headers.

The spec also says a server that emits 415 SHOULD tell you what it does accept. For a PATCH, that’s the Accept-Patch header (RFC 5789). Some APIs advertise supported types in the error body or an Accept-Post-style header. A polite 415 hands you the answer. A lazy one just says “Unsupported Media Type” and leaves you to guess — which is usually why you’re here.

Top 3 Causes

  1. A missing or wrong Content-Type header - The overwhelming favorite. You send a JSON string in the body but never set Content-Type: application/json, so the client defaults to something else — curl -d sends application/x-www-form-urlencoded, a bare fetch with a string body sends text/plain. The server’s binding layer (Spring’s consumes, ASP.NET’s [Consumes], an Express json() parser mounted only for JSON) sees a type it wasn’t told to handle and answers 415 before your data is ever parsed.

  2. A subtype or charset the server won’t match - You send application/json; charset=utf-8 and a strict endpoint registered only bare application/json. Or the API expects a vendor type like application/vnd.api+json and you sent plain application/json. The bytes are identical JSON; the media-type string doesn’t match the server’s allowlist, so it’s rejected on the string comparison alone.

  3. A Content-Encoding the server can’t decode - You gzip the request body and set Content-Encoding: gzip to save bandwidth, but the server or framework doesn’t support compressed request bodies (many don’t — compression is usually a response-only feature). It can’t decode the payload into the declared media type, so it returns 415. This one bites people who add client-side compression and forget the server has to opt in to decompressing uploads.

Diagnose with DechoNet

  • HTTP Check to see the exact status line and the headers the endpoint returns to a clean request. A 415 is tied to a specific write with a specific Content-Type, so a neutral check usually comes back 200 or 405 — and that split is the point. If the route answers normally to a plain request, the 415 lives in your header versus what the endpoint consumes, not in a broken deployment. Watch the response headers for any Accept-Patch or advertised media types; that’s the server telling you what it actually wants.

Resolution Checklist

  • Print the Content-Type your client is actually sending, not what you think it’s sending. curl -v or the browser network tab shows the real header. Nine times out of ten it’s missing, or it’s text/plain, or it’s form-encoded when the API wants JSON.
  • Set the header explicitly to what the endpoint documents — usually application/json. If the API uses a vendor type (application/vnd.api+json, application/merge-patch+json), match it exactly, including the suffix.
  • Check the charset. If the server registered bare application/json, dropping ; charset=utf-8 can be the entire fix. If it wants the charset, add it. Match the allowlist character for character.
  • If you compressed the request body, remove Content-Encoding: gzip (or confirm the server supports decompressing uploads). Response compression and request compression are separate features and most servers only do the former.
  • Confirm it isn’t a 406 in disguise. If your Accept header is the mismatch and the response body is fine, you want 406, not 415 — different header, different fix.
  • Re-run the request and confirm the endpoint now returns 2xx instead of 415.

When to Escalate

  • If a request that worked yesterday started returning 415 today with no client change, suspect a proxy, CDN, or WAF that’s rewriting or stripping the Content-Type header in transit. An HTTP Check that shows the endpoint healthy to a direct request, versus 415 through the edge, points straight at the middlebox.
  • If you own the API and legitimate clients are hitting 415 on a type you meant to support, widen the endpoint’s accepted media types and make the 415 body list what you consume — a bare “Unsupported Media Type” with no Accept-Patch or allowlist is a support ticket waiting to happen.

Related Tools

Related Guides

Share this guide

[Ad] Guide Detail Inline
← Back to All Guides