400 Bad Request: what it means and how to fix it
The server couldn't understand the request. The fixes for visitors (usually cookies) and for developers: malformed JSON, missing parameters and headers a proxy refuses.
· 4 min read · By the Spot Downtime team
400 Bad Request is the server saying “I can't make sense of what you sent”. Unlike a 500, the server isn't broken: it looked at the request and rejected it before doing any real work. The trick is finding out which part of the request it didn't like, because the error page rarely says.
If you're a visitor seeing it
Almost every 400 a normal visitor sees comes from something stored in the browser, not from the site itself:
- Corrupted or oversized cookies. Clear the cookies for that one site (not your whole browser) and reload. nginx shows this case as
400 Bad Request: Request Header Or Cookie Too Large. - A mangled link. A URL with a stray
%, a space or a broken encoding. Retype the address or go to the home page. - A stale form. Submitting a form that sat open for hours can send an expired security token. Reload the page and submit again.
If it works in a private window, it was cookies or cache. If it fails everywhere, the problem is on the site's side.
If it's your site or API
Malformed body
The most common API cause: invalid JSON (a trailing comma, single quotes, an unescaped character) or a body that doesn't match the Content-Type header. Validate the exact bytes you send, not the object you think you send:
curl -i https://api.example.com/orders \
-H "Content-Type: application/json" \
-d '{"sku": "A-100", "qty": 2}'A well-behaved API puts the reason in the response body, such as {"error": "qty must be a number"}. Read it before anything else. (If the body is valid JSON but the values are wrong, many APIs use 422 instead.)
Missing or invalid parameters
A required query parameter that's missing, a date in the wrong format, an ID that isn't a number. Compare the request to the API docs field by field.
Headers the server refuses
Headers that are too large, duplicated (two Host headers), or invalid for the protocol. Proxies are stricter than application servers, so a request that works directly against your app can get a 400 from nginx or a load balancer in front of it.
HTTP sent to an HTTPS port
nginx answers 400 The plain HTTP request was sent to HTTPS port when something talks plain HTTP to port 443. Usually it's a health check, a load balancer or a script configured with http://example.com:443.
Finding which request failed
Look in the access log of whatever sits closest to the client. If the 400 is in nginx's log but the request never reached your application's log, the proxy rejected it, and its error.log usually says why:
sudo grep '" 400 ' /var/log/nginx/access.log | tail -n 20
sudo tail -n 50 /var/log/nginx/error.logShould a 400 wake anyone up?
Spot Downtime treats any 4xx from a monitored URL as down, so a broken proxy rule shows up as an incident with the status code attached, not as a support ticket a day later.
Keep reading
- HTTP errors · Troubleshooting500 Internal Server Error: how to find the cause and fix itA 500 hides its reason on purpose. Where to look first, the usual causes from unhandled exceptions to full disks, and the extra checks for WordPress and PHP sites.October 5, 2026 · 5 min read
- HTTP errors · Troubleshooting404 Not Found: fix broken pages, missing routes and soft 404sWhich 404s you can ignore, which ones cost you visitors and rankings, and how to fix a whole site or section that suddenly returns Not Found.October 5, 2026 · 4 min read