HTTP 400

400 Bad Request

Client Error

The server cannot or will not process the request because it appears to be malformed. Invalid syntax, framing errors, deceptive request routing, or a request body that violates the declared Content-Type. 400 is intentionally generic; it signals a problem at the protocol or parser level rather than a business rule violation, which is what 422 exists for. A well-designed API returns 400 only when the request literally cannot be parsed.

When does this happen?

Return 400 when the request itself is broken at the protocol or syntax level. Malformed JSON in a POST body, a Content-Length that does not match the body, a missing required query parameter that is needed before any business logic can run, or a request line that violates the HTTP grammar all warrant 400. Most APIs return a JSON error body describing what went wrong, ideally referencing a specific field or token. Browsers do not surface 400 specially. The page or fetch call simply fails. Watch the distinction between 400 (the request is broken) and 422 (the request is well-formed but the data is invalid). Mixing them up makes client error handling harder because clients cannot tell whether to retry the same payload, fix the structure, or fix the values. Some frameworks default to 400 for any validation error, which is sloppy but widespread. If you control the API, separate the two.

Common causes

How to fix it

Real-world examples

Client sends POST /v1/users with a body of {"email":"[email protected]",} where the trailing comma makes the JSON invalid.
Server returns 400 with body {"error":"invalid JSON","position":21}. Client retries with corrected JSON.
Browser submits a form with a session cookie that has been corrupted by a buggy extension.
Server returns 400 because it cannot parse the cookie. User clears cookies and the next request succeeds.
Client sends GET /search with no q parameter to an endpoint that requires it.
Server returns 400 with {"error":"missing required parameter: q"}. UI surfaces the validation message inline.
Misconfigured client sends POST with Content-Type: application/json but a body of [email protected]&password=secret.
Server tries to parse the body as JSON, fails, and returns 400. Client must either fix the Content-Type or send a JSON body.
URL contains a parameter list so long it exceeds Nginx's 8KB request line limit.
Nginx returns 400 before the request reaches the application. The client must POST the data instead.
Reverse proxy detects conflicting Content-Length and Transfer-Encoding headers (a request-smuggling indicator).
Proxy returns 400 and refuses to forward the request. The client must clean up the request framing.

Debugging

How it differs from related codes

HTTP 401

401 is specifically about missing or invalid authentication. 400 is about the request being broken at the syntax or protocol level. Auth is unrelated.

HTTP 404

404 means the URL does not exist. 400 means the URL exists but the request is malformed. The distinction matters because 400 is the client's fault to fix, 404 may be either.

HTTP 422

422 means the request was syntactically valid but failed business rules (e.g., email already taken). 400 means parsing failed. Conflate them and clients cannot tell what to fix.

Related status codes

401 403 404 405 415 422 500

See HTTP 400 in your redirect chains?

Check your URLs with checkredirects.io