HTTP 400 Bad Request

Quick answer

HTTP 400 Bad Request means the server could not process the request because it was malformed — often invalid JSON, a missing required field, or a wrong parameter.

What HTTP 400 means

400 Bad Request indicates a client-side error in the request itself. The server understood the request line but the payload, query parameters, or headers were malformed. In JSON APIs the single most common cause is a body that is not valid JSON — a trailing comma, a missing quote, or a truncated payload.

Common causes

Example JSON error response

{
  "error": "Bad Request",
  "message": "Invalid JSON: unexpected token at position 42",
  "status": 400
}

Raw HTTP response

HTTP/1.1 400 Bad Request
Content-Type: application/json

How to troubleshoot HTTP 400

400 vs 422 — what's the difference?

400 Bad Request means the request itself is malformed — for a JSON API, usually the body isn't valid JSON at all. 422 Unprocessable Entity means the JSON is syntactically valid but fails validation (a field is the wrong value, an email is malformed, a business rule is broken). Rule of thumb: if the parser can't even read the body, it's 400; if it reads fine but the data is wrong, it's 422.

Handling HTTP 400 in client code

A 400 is almost always a bug in the request your code built, not a server problem — so surface the server's error message rather than retrying. Retrying an identical malformed request will just 400 again:

const res = await fetch('/api/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});

if (res.status === 400) {
  const err = await res.json();        // read the server's reason
  console.error('Bad request:', err.message);
  return;                              // do NOT blindly retry a 400
}

The most common cause in JS is hand-building a JSON string instead of using JSON.stringify(), which introduces trailing commas or unquoted keys. If you're debugging a malformed body, paste it into the JSON Validator — and see how to read a minified JSON API response.

Returning 400 in different frameworks

FrameworkHow to return 400
Express (Node.js)res.status(400).json({ error: "Bad Request" })
Flask (Python)return jsonify(error="Bad Request"), 400
FastAPI (Python)raise HTTPException(status_code=400, detail="...")
Spring Boot (Java)ResponseEntity.badRequest().body(...)

Frequently Asked Questions

What causes a 400 Bad Request in a JSON API?

Most often the request body is not valid JSON — a trailing comma, a missing quote, or a truncated payload. Other causes are missing required fields, wrong field types, or an incorrect Content-Type header.

How do I fix a 400 Bad Request?

Validate the request body as JSON, confirm all required fields are present and correctly typed, and check the Content-Type header. Pasting the body into a JSON validator quickly reveals syntax errors.

What is the difference between 400 and 422?

400 means the request is malformed (e.g. invalid JSON the server cannot parse). 422 means the JSON is valid but fails semantic validation. Use 400 for unparseable requests, 422 for valid-but-rejected data.

Should I retry a request that returned 400?

No. A 400 means the request was malformed, so retrying the identical request will fail the same way. Fix the request — correct the JSON, add the missing field, or set the right Content-Type — then send it again. Retries are appropriate for transient 5xx errors, not 400.

Why does my API return 400 with a valid-looking body?

Common culprits: a missing or wrong Content-Type: application/json header (so the server never parses the body as JSON), a trailing comma from hand-built JSON, or a field with the wrong type. Send the body through JSON.stringify() and confirm the Content-Type header.

Working with a JSON API response?

Format and inspect any response in your browser — nothing is uploaded.

JSON Formatter JSON Validator All HTTP Status Codes
About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.