400 🌐 HTTP

HTTP 400 Bad Request

The server could not understand the request because its syntax, headers or body are malformed or invalid.

Seen on: JavaScript PHP Nginx Apache REST API

Meaning

A 400 means the problem is on the client side: the server received the request but refuses to process it because something about it is broken — invalid JSON, a missing required parameter, an oversized or corrupt cookie, or a header the server can’t parse.

Unlike 422 (valid syntax but invalid data), 400 usually means the request couldn’t even be parsed properly. Many APIs, however, use 400 for every validation error, so always read the response body for details.

Common causes

  • Malformed JSON body (trailing comma, single quotes, unescaped characters)
  • Missing Content-Type: application/json header, so the server can’t parse the body
  • Required query parameter or field missing
  • Oversized or corrupted cookies (common on Nginx: "Request Header Or Cookie Too Large")
  • Invalid characters in the URL that weren’t URL-encoded
  • Sending a body with a GET request to a server that rejects it
  • Wrong data type, e.g. a string where the API expects a number

⚡ Quick fix

  1. Read the response body — most APIs say exactly which field is wrong
  2. Validate your JSON (paste it into the JSON error finder tool)
  3. Set Content-Type: application/json when sending JSON
  4. URL-encode query parameters (encodeURIComponent in JS, urlencode in PHP)
  5. In a browser, clear cookies for the site and retry

Detailed fix by platform

JavaScript

  1. Serialize the body and set the content type explicitly.
    javascript
    const res = await fetch('/api/users', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name: 'Asha', age: 31 }),   // not a raw object
    });
    if (!res.ok) console.error(res.status, await res.text()); // read the server's reason

PHP

  1. Read JSON input with json_decode(file_get_contents('php://input'), true) — $_POST is empty for JSON bodies.
  2. Check json_last_error_msg() and return a clear 400 message naming the bad field.

Nginx

  1. For "400 Request Header Or Cookie Too Large", raise the header buffer size.
  2. In the http or server block:
    nginx
    large_client_header_buffers 4 32k;
  3. Reload: sudo nginx -t && sudo systemctl reload nginx.

REST API

  1. Log the raw request body and headers on the server for failing calls.
  2. Return structured validation errors ({"error":"invalid_field","field":"email"}) so clients can self-correct.

Code examples

Classic cause: sending an object instead of a JSON string

javascript
// ❌ body becomes "[object Object]" → 400
fetch('/api/login', { method: 'POST', body: { user: 'a' } });

// ✅
fetch('/api/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ user: 'a' }),
});

The server receives the literal text [object Object], which isn’t valid JSON.

Inspect with curl

bash
curl -i -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name":"Asha"}'

-i prints status and headers so you can see the exact error body.

How to diagnose

  1. Response body — What field or header does the server complain about?
  2. Request body — Is it valid JSON / form data and correctly encoded?
  3. Headers — Is Content-Type correct? Are cookies or headers unusually large?
  4. URL — Are query parameters present and URL-encoded?
  5. Server logs — Does the framework log a parse or validation exception?

🧠 Still stuck? Analyze your error

Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.