So, you've run into the 415 Unsupported Media Type error. It’s a frustrating but common roadblock for developers. In simple terms, it means you sent something to the server, but it arrived in a format the server can't understand or wasn't expecting.
Think of it like trying to hand a letter written in a foreign language to a post office that only processes English. They see you have a letter, but they have no idea how to read it, so they have to send it back. The problem isn't the post office (the server); it's the letter itself (your request). This is why a 415 is a client-side error—the fix is on your end.
What Is the 415 Unsupported Media Type Error?

When you see a 415 error, it's the server's way of saying, "I see you sent me data, but I don't know what to do with it." The server is up and running just fine, but your request didn't follow the rules for how data should be packaged.
This error almost always pops up when you're making POST or PUT requests, which are designed to send data to a server. To interpret that data correctly, the server looks for a specific instruction in the request: the Content-Type header. If that header is missing, wrong, or lists a format the server isn't configured to accept, it throws its hands up and sends back a 415.
The Core Problem and Solution
The root of the issue is a mismatch between the data you're sending and the Content-Type header you've set. For example, you might have a perfectly valid JSON payload, but if you forget to include the Content-Type: application/json header, the server is left guessing. It might try to read it as plain text, fail, and immediately reject the request.
The 415 error is fundamentally about expectations. The server publishes a list of acceptable "media types," and your request must clearly state that it's sending one of them.
This has become a frequent hurdle for developers, especially as APIs have grown to handle over 83% of all internet traffic. A simple header mismatch can bring a data exchange to a screeching halt. If you want to dive deeper into how central APIs have become, check out the full 2023 report from Postman.
Getting this right is all about ensuring data arrives in a way the server can process reliably. The table below breaks down the key details of the 415 error.
The HTTP 415 Error at a Glance
This table gives you a quick summary of what the 415 error code means, where it comes from, and how to start fixing it.
| Aspect | Explanation |
|---|---|
| Error Code | HTTP 415 Unsupported Media Type |
| Error Type | Client-Side (4xx) |
| Core Problem | The Content-Type header is missing, incorrect, or unsupported by the server. |
| Common Triggers | POST, PUT, or PATCH requests that include a request body. |
| Primary Solution | Make sure the Content-Type header is present and correctly describes the data format in the request body. |
In short, the 415 error is your cue to double-check your request headers and make sure they perfectly align with the data payload you're sending.
Understanding Content Negotiation and HTTP Headers

When you run into a 415 error, it’s not just a random failure—it’s the server telling you something very specific: "I don't understand the format of the data you just sent me." To get to the bottom of this, we need to look at the quick, automated "conversation" that happens with every API request.
This back-and-forth is called content negotiation. It all hinges on a couple of simple HTTP headers that act like a handshake, setting the rules before any data is exchanged. The two most important players here are Content-Type and Accept.
The Role of the Content-Type Header
Think of the Content-Type header as a label on a package you're mailing. It tells the recipient exactly what’s inside and how to open it. If you send a box of puzzle pieces but label it "books," the recipient is going to be confused and probably won't know what to do with it.
It's the same with APIs. The Content-Type header is your client's way of telling the server, "Hey, the data I'm sending in the body of this request is formatted as JSON." Without this header, or with the wrong one, the server has to guess. Most modern servers are configured not to guess; they'll just reject the request with a 415 error.
In the world of web development, a few media types show up all the time:
application/json: The go-to for most modern REST APIs. It’s perfect for sending structured data.application/xml: You'll see this with older web services, especially those built on SOAP.application/x-www-form-urlencoded: The classic format used when you submit a simple HTML web form.multipart/form-data: This one is essential for forms that include file uploads alongside regular text fields.
The key takeaway is that the Content-Type header must accurately describe the data you’re sending. If you're new to this, grasping how APIs handle data formats is a big first step. Our guide on how to build a REST API is a great place to start.
How the Accept Header Completes the Conversation
While Content-Type is about what you send, the Accept header is all about what you want to get back. It's the client telling the server, "After you process my request, please send the response back as JSON, because that's what I know how to read."
The server looks at the Accept header and checks if it can generate a response in one of the requested formats. This two-way communication ensures the client and server are always on the same page.
The Big Picture: The
Content-Typeheader is about the request payload (client to server), while theAcceptheader is about the response payload (server to client). A 415 error is almost always caused by an issue with theContent-Typeheader.
This isn't just a theoretical problem. According to a 2023 Gartner survey, a mismatch in data formats was responsible for a frustrating 32% of REST API integration failures. The good news is that it’s an easy fix. The same report noted that simply ensuring the correct headers were in place reduced these errors by an incredible 72%. You can learn more about the HTTP 415 status code on MDN Web Docs, which provides the official specification as defined in RFC 7231.
Alright, let's get practical. You know the theory behind the 415 Unsupported Media Type error, but the real question is: why is it haunting your API calls right now? Let's switch from textbook definitions to a real-world diagnostic checklist.
Think of this as a debugging session. We're going to walk through the usual suspects, starting with the most common culprits. The good news is that most 415 errors are caused by a few simple, easy-to-fix mistakes.
Missing or Incorrect Content-Type Header
This is the big one. Honestly, nine times out of ten, a 415 error comes down to a problem with the Content-Type header. You've painstakingly built the perfect JSON payload, fired off your POST request, and the server just slaps it away. Why? You probably forgot to tell the server what you were sending.
If you don't include a header like Content-Type: application/json, the server has to guess what kind of data is in the request body. Most servers won't guess; to be safe, they'll just reject the request outright. This is an incredibly common trip-up when using tools like JavaScript's fetch API, which won't add this header for you automatically, even if your data is a perfectly stringified JSON object.
The other side of the coin is sending a contradictory header. Maybe you copied an old request and forgot to change the header from application/json to application/xml. The server sees the mismatch and immediately throws a 415.
The golden rule is simple: The
Content-Typeheader must always be present, and it must perfectly match the format of the data in your request body. No exceptions.
Getting this right from the start will save you countless hours of banging your head against the keyboard.
Malformed Request Body
So your Content-Type header is present and correct, but you're still getting that frustrating 415. What's next? It's time to check the payload itself. Sometimes, the body of your request is simply broken.
This happens all the time with JSON. A single misplaced comma, a forgotten quote, or an unescaped character can render the entire object invalid. When the server sees the Content-Type: application/json header, it trusts you. It fires up its JSON parser, but the parser immediately crashes when it hits the syntax error. Since it can't process the data as the promised media type, it has no choice but to send back a 415.
A few things to look for here:
- Syntax Errors: Is your JSON actually valid? Run it through a linter or an online validator to be sure. It's the quickest sanity check you can do.
- Empty Body: Did you send a
Content-Typeheader but forget to include a request body? Some servers will interpret this as a 415 because there's no "content" to match the "type." - Incorrect Serialization: Before sending, make sure your data structure was actually turned into a string. Forgetting to use a function like
JSON.stringifyis a classic mistake.
Server-Side Misconfiguration
Finally, if you've triple-checked your headers and validated your payload, it's possible the issue isn't on your end. The problem might be with the server itself.
The specific API endpoint you're trying to use might simply not be programmed to handle the data format you're sending. For example, a developer might have built an endpoint that only accepts old-school application/x-www-form-urlencoded data and completely forgot to add support for application/json. When your beautifully formatted JSON request arrives, the server knows what it is but also knows it can't do anything with it.
This is less frequent than a simple client-side mistake, but it's a definite possibility. Your next step should be to dive into the API's documentation. Check which media types that specific endpoint officially supports. If the docs are vague or you still can't find the issue, it might be time to check the server's code or reach out to the API provider.
To help you diagnose the problem faster, here's a quick reference table breaking down these common causes and how to spot them.
Common Causes and Diagnostic Clues
| Cause | Symptom or How to Check | Common Scenario |
|---|---|---|
Missing Content-Type Header | Look at your request headers in browser dev tools or your API client (like Postman). The Content-Type header is completely absent. | A fetch call in JavaScript without manually setting the headers object. |
Incorrect Content-Type Value | The Content-Type header is present, but its value doesn't match the body. Content-Type: text/plain is sent with a JSON object. | Copy-pasting a cURL command and forgetting to update the -H flag for the new data format. |
| Malformed Payload | The header is correct, but the request body has a syntax error (e.g., a trailing comma in JSON). Use a linter to validate your payload. | Manually building a JSON string and making a typo. |
| Server Not Configured for Type | Your request is perfect, but the error persists. Check the API documentation for the endpoint's accepted media types. | You're sending application/json to a legacy endpoint that was only ever designed to accept application/xml. |
Think of this table as your first line of defense. By checking these three areas—the header's existence, the header's accuracy, and the body's validity—you'll solve the vast majority of 415 errors you encounter.
How to Fix the 415 Error with Practical Examples

Alright, enough with the theory. Let's get down to brass tacks and actually fix this unsupported media type error. This is where we roll up our sleeves with practical, copy-paste solutions that you can use right now.
We’ll start on the client-side with cURL and Postman, which is often where the problem lies. Then, we’ll jump over to the server and walk through the common setup mistakes in popular backend frameworks. The goal is simple: get your app and server speaking the same language again.
Fixing the Request with cURL and Postman
The fastest way to hunt down a 415 error is to take your own application code out of the equation. Tools like cURL and Postman are your best friends here because they give you surgical control over the HTTP request, especially its headers.
A classic mistake is sending a JSON object but forgetting to tell the server what it is. Here’s what that looks like in a cURL command that's almost guaranteed to fail.
This request will likely fail with a 415 error
curl -X POST https://api.example.com/items
-d '{"name": "New Item", "price": 99}'
What's wrong? By default, cURL sends that payload with a Content-Type of application/x-www-form-urlencoded. The server gets a request that says it's form data but contains a JSON string, triggering the mismatch and the 415 error.
The fix is to be explicit. You just need to add the correct header with the -H flag.
Correct: Explicitly setting the Content-Type header
curl -X POST https://api.example.com/items
-H "Content-Type: application/json"
-d '{"name": "New Item", "price": 99}'
That one simple line tells the server, "Heads up, you're about to receive JSON," and just like that, the unsupported media type error vanishes.
Postman makes this even simpler. When you build a request and select "raw" and "JSON" as the body type, Postman automatically adds the Content-Type: application/json header for you. This provides a huge clue: if your request works in Postman but fails in your application, the culprit is almost certainly that your code is forgetting to add the correct header.
Configuring Your Node.js and Express Server
Moving over to the server, if you're building a Node.js API with Express, the number one cause of a 415 error is forgetting to use the right middleware. Out of the box, Express has no idea what to do with a raw JSON payload.
You have to teach it. The built-in express.json() middleware acts as a translator. It checks incoming requests for a Content-Type: application/json header and, if it finds one, it parses the JSON string into a usable object and attaches it to req.body.
Here’s an Express server that doesn't know how to speak JSON.
// Before: This server will return a 415 for JSON requests
const express = require('express');
const app = express();
app.post('/api/users', (req, res) => {
// req.body will be undefined here
const { name } = req.body;
res.send(User ${name} created!);
});
app.listen(3000);
To get this working, you only need to add one line of code: app.use(express.json());. This tells your entire application to start listening for and parsing JSON.
// After: Correctly configured with express.json()
const express = require('express');
const app = express();
// This middleware is the key to parsing JSON
app.use(express.json());
app.post('/api/users', (req, res) => {
// req.body is now populated with the parsed JSON
const { name } = req.body;
res.send(User ${name} created!);
});
app.listen(3000);
With that middleware in place, your Express server can now understand JSON payloads, resolving the 415 error for good. For more complex setups, you can dive deeper in our complete guide on Express error handling.
Solving the 415 Error in Python Frameworks
If you're a Python developer, you'll encounter similar scenarios in frameworks like Django and Flask. They also need to be told how to handle different media types.
In Django with Django REST Framework (DRF):
DRF is built on a system of "parsers" that are responsible for interpreting incoming request data. For application/json, the JSONParser is what you need. While it’s typically enabled by default, it's easy to accidentally remove it during custom configurations.
You can make sure it’s active by checking your settings.py file.
In your settings.py
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
# You can also add other parsers if needed
# 'rest_framework.parsers.FormParser',
# 'rest_framework.parsers.MultiPartParser',
]
}
This configuration ensures that when DRF sees a request with Content-Type: application/json, it knows to use the JSONParser to process the body and make it available in your view.
In Flask:
A vanilla Flask application is more hands-on. It won't parse JSON for you automatically. The key is to use the request.get_json() method. Simply trying to read request.data won't work as expected if the client is sending JSON.
The
request.get_json()method in Flask is specifically designed to handle this. It checks theContent-Typeheader and, if it'sapplication/json, parses the body for you. If the header is missing or incorrect, it will returnNone.
Here’s the right way to handle a JSON POST request in a Flask endpoint.
from flask import Flask, request, jsonify
app = Flask(name)
@app.route('/api/products', methods=['POST'])
def create_product():
# Use get_json() to parse the incoming JSON
product_data = request.get_json()
if not product_data:
return jsonify({"error": "Invalid JSON or Content-Type header missing"}), 415
# Now you can work with the data
product_name = product_data.get('name')
return jsonify({"message": f"Product '{product_name}' created"}), 201
By using request.get_json(), you’re creating a more resilient endpoint that correctly processes JSON and politely rejects requests that don't follow the rules. This proactive approach is essential. Data shows these errors are surprisingly common; for instance, HTTP 415 errors jumped 27% year-over-year on Cloudflare's network, and a whopping 62% of those were caused by mobile apps sending incorrectly formatted data.
Alright, you've nailed the basics of the Content-Type header, but what happens when the 415 error shows up in trickier situations? Sometimes, the problem goes beyond a simple mismatched JSON header, especially when you're dealing with file uploads, GraphQL, or enterprise-grade systems.
Let's dive into these advanced scenarios. Getting a handle on them will not only help you squash the unsupported media type error but also build more resilient and flexible APIs from the ground up.
Tackling File Uploads with Multipart Form Data
When your API needs to accept files—like a user's profile picture or a CSV report—you'll quickly meet multipart/form-data. This media type is the web's standard for sending files and text data together in a single request. Think of it like a shipping container with specially marked compartments for a user's name, email, and the actual photo file.
A classic mistake is trying to cram a file into an application/json payload. It just won’t work. JSON is designed for text-based data structures, not raw binary file data. If you try, the server will see a jumbled mess of text instead of the file stream it expects, triggering an immediate unsupported media type error.
The multipart/form-data type elegantly solves this. It constructs a request body with several distinct "parts," each with its own set of headers.
- Text Fields: A part for a text field like
usernamegets aContent-Dispositionheader that names the field. - File Fields: A part for a file also gets a
Content-Dispositionheader, but it includes the filename and its ownContent-Typeheader, likeimage/jpeg.
To handle this on the backend, you'll need middleware built specifically for parsing these multipart requests. For instance, a Node.js developer using Express would reach for a library like Multer. Multer specializes in processing multipart/form-data, making it simple to grab both the text fields and the uploaded files from the request.
The 415 Error in a GraphQL World
GraphQL APIs are a different beast. By design, a standard GraphQL server is incredibly strict and usually only accepts one media type for its operations: application/json. This isn't a limitation; it's a feature that enforces a consistent, predictable structure for all queries and mutations.
You'll run into a 415 error with GraphQL if your client sends a request with the wrong Content-Type. This often happens by accident, maybe from a misconfigured tool that defaults to text/plain or if you try sending form data directly to your main GraphQL endpoint.
The golden rule for GraphQL is consistency. Unless you're using a special setup for file uploads, every
POSTrequest to your GraphQL endpoint must have theContent-Type: application/jsonheader and a body containing the standardquery,operationName, andvariablesfields.
But what if you do need to upload files with GraphQL? You can't just switch the content type to multipart/form-data and hope for the best. Instead, you need a server-side implementation that follows a multipart request specification. Libraries like graphql-upload for Node.js are designed for this. They act as a middleman, intercepting the multipart request, extracting the files, and then making them available to your GraphQL resolvers.
Best Practices for Building Resilient APIs
Moving from fixing errors to preventing them is the mark of a seasoned developer. A great way to do this is by enforcing content type validation at the edge of your infrastructure, before a bad request ever touches your application code.
An API Gateway is the perfect tool for the job. It acts as a single, unified entry point for all incoming traffic. You can configure the gateway to inspect every request and immediately reject any that lack an approved Content-Type. This strategy pays off in several ways:
- Centralized Rules: You define your validation logic once in the gateway, rather than duplicating it across dozens of microservices.
- Tighter Security: It filters out malformed requests from the start, helping protect against certain attacks that exploit inconsistent data handling.
- Less Server Strain: Your application servers are shielded from invalid requests, so they don't waste precious CPU cycles processing data that was doomed to fail.
By combining good client-side habits with strong server-side validation and architectural patterns like an API Gateway, you can create systems where the 415 unsupported media type error is a true rarity, not a daily headache.
A Practical Checklist for Dodging 415 Errors
Alright, we've walked through the what and why of the 415 Unsupported Media Type error. Now, let's boil it all down into a simple checklist you can actually use. Think of this as your pre-flight check before you send a request into the wild.
Turning these steps into muscle memory will save you countless hours of banging your head against the wall. You'll spend less time debugging and more time building.
Your Pre-Request Checklist
Here are the habits that will keep the 415 error from ever crashing your party.
Set your
Content-Typeevery single time. For anyPOST,PUT, orPATCHrequest that sends a body, explicitly set theContent-Typeheader. Never, ever assume a library or framework will magically do it for you.Make sure the payload is what the header says it is. If your header says
application/json, the request body better be a perfectly formatted JSON object. This simple mismatch is the root cause of most 415s.Validate your payload's syntax. A single rogue comma or a missing bracket in your JSON is enough for the server to throw up its hands and say, "I can't read this!" Use a linter or validator to catch these simple mistakes before you hit send.
Confirm the server is ready for your data. Is your Express app actually using the
express.json()middleware? Does your Django API have the right parsers enabled? The server has to be configured to listen for the specific media type you're sending.Use an API client as a sanity check. When in doubt, recreate the request in a tool like Postman. It gives you a clean environment to isolate the problem and often makes header or body issues glaringly obvious.
At the end of the day, handling media types correctly is about clear communication. It’s the foundation of a reliable, predictable API where the client and server understand each other perfectly.
Getting these habits down doesn't just fix a single error; it's a huge step toward better API design. When your API's expectations are clear, it's easier to use and document. Speaking of which, if you want to make your API truly great, check out our guide on how to write API documentation that developers will actually thank you for.
Make these checks second nature, and the 415 error will become a distant memory.
Frequently Asked Questions
Even after you get the hang of media types, a few tricky questions always seem to surface. Let's clear up some of the most common points of confusion around the 415 error so you can tackle these scenarios with confidence.
What Is the Difference Between a 415 and a 400 Error?
It’s incredibly common to mix these two up, but they point to completely different problems. The easiest way to remember the distinction is to think about when the server rejects the request.
A 415 Unsupported Media Type error is about the packaging. The server is essentially saying, "I don't know how to open this." The
Content-Typeheader is either missing, incorrect, or specifies a format the server simply isn't configured to handle. The server stops before it even tries to look at the data inside.A 400 Bad Request error is a more general problem with the contents. The server successfully opened the package because the
Content-Typewas fine, but it found something wrong with the data itself. Maybe you sent syntactically valid JSON that was missing a requiredemailfield, or a field likeagecontained a string"twenty"instead of a number.
In short, a 415 means the server can't read the format. A 400 means it read the format just fine but found the data itself was invalid.
Why Don’t GET Requests Usually Cause a 415 Error?
You’ll almost exclusively run into a 415 error on requests that carry a payload, like POST, PUT, or PATCH. These methods are designed to send data to the server, making the Content-Type header absolutely critical for telling the server how to interpret that incoming data.
A GET request, on the other hand, is meant to retrieve data from the server. According to the HTTP specification, a GET request shouldn't have a request body. Since there's no data payload to parse, there's no need for a Content-Type header, and therefore no chance of an unsupported media type mismatch. If you ever feel the need to send a body with a GET request, it's a strong sign you should probably be using a different HTTP method.
This flowchart gives a great visual of the checks you can run to avoid a 415 error before it even happens.

The key takeaway is that preventing a 415 is all about making sure the client and server are perfectly aligned on the data format.
How Should an API Handle Multiple Media Types?
It's perfectly fine—and often good practice—for an API to support multiple media types on the same endpoint. A robust server will inspect the Content-Type header of an incoming request and route it to the appropriate parser.
For instance, an endpoint could be designed to accept both JSON and XML. When a request comes in, the server checks the header. If it sees application/json, it hands the payload to its JSON parser. If it sees application/xml, it sends it to the XML parser instead. This makes your API more flexible for different clients.
At Backend Application Hub, we publish in-depth guides and comparisons to help you solve complex backend challenges like API design and error handling. For more hands-on tutorials, check out our work at Backend Application Hub.
















Add Comment