jsonerrorsapihttpdebugging

415 Unsupported Media Type — Fix JSON API Errors

·5 min read

What Is HTTP 415 Unsupported Media Type?

A 415 Unsupported Media Type response means the server refuses your request because it does not recognize or accept the Content-Type of the request body you sent. The request itself is well-formed, but the server will not process this type of content.

This almost always happens when you send a JSON body without the `Content-Type: application/json` header.

The Most Common Cause

Missing or wrong Content-Type header in the request:

javascript
// WRONG — no Content-Type header
fetch('/api/users', {
  method: 'POST',
  body: JSON.stringify({ name: 'Ravi' }),
});
javascript
// CORRECT
fetch('/api/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ name: 'Ravi' }),
});

Without the Content-Type header, the browser defaults to `text/plain;charset=UTF-8` or `application/x-www-form-urlencoded`. The server rejects it because it does not know how to parse the body.

Fix in JavaScript fetch

javascript
const response = await fetch('/api/orders', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Bearer ' + token,
  },
  body: JSON.stringify(payload),
});

Fix in axios

axios sets Content-Type automatically when you pass an object as data:

javascript
// axios automatically adds Content-Type: application/json
await axios.post('/api/orders', payload);

// If you stringify manually, you must set the header yourself
await axios.post('/api/orders', JSON.stringify(payload), {
  headers: { 'Content-Type': 'application/json' },
});

Do not stringify the payload when passing it to axios — pass the plain object and axios handles serialization.

Fix in Python requests

python
import requests

# WRONG — sends form-encoded body, not JSON
requests.post('/api/orders', data={'name': 'Ravi'})

# CORRECT — json= parameter serializes and sets Content-Type automatically
requests.post('/api/orders', json={'name': 'Ravi'})

# Also correct — manual approach
requests.post('/api/orders',
    data=json.dumps({'name': 'Ravi'}),
    headers={'Content-Type': 'application/json'})

Fix in curl

bash
# WRONG — no Content-Type
curl -X POST http://api.example.com/users -d '{"name":"Ravi"}'

# CORRECT
curl -X POST http://api.example.com/users   -H 'Content-Type: application/json'   -d '{"name":"Ravi"}'

Server-Side: What Triggers 415

Express (Node.js) — must use express.json() middleware:

javascript
app.use(express.json()); // parses application/json bodies
// Without this, Express returns 415 for JSON requests

FastAPI (Python) — define the parameter as a Pydantic model:

python
from pydantic import BaseModel

class UserCreate(BaseModel):
    name: str
    email: str

@app.post("/users")
async def create_user(user: UserCreate): # FastAPI expects JSON body
    ...

Django REST Framework — default parsers accept JSON, but check your settings:

python
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
    ]
}

Checklist to Fix 415

1. Add `Content-Type: application/json` to your request headers 2. If using axios, pass a plain object (not a stringified string) to `data` 3. If using Python requests, use `json=` not `data=` 4. On the server, verify JSON body parsing middleware is enabled 5. For REST endpoints, set `Accept: application/json` too so the server returns JSON errors instead of HTML

Validate your JSON payload at /json-validator before sending it to confirm the syntax is correct.

Try JSON Validator

Confirm your request body is valid JSON before setting Content-Type.