Error guide

400 Bad Request

The server could not parse or would not accept the request as sent — it was malformed before any logic ran.

A 400 Bad Request says the server refused the request because something about it was wrong at the protocol or parsing level. This is not a rejection on business grounds — that would be a 422 or a 409 — it is the server saying it could not make sense of what arrived.

It is generated at two very different depths, and knowing which one you are looking at halves the work. A web server or reverse proxy generates a 400 before your application sees anything: an oversized header, an invalid character in the request line, a malformed chunked body, a hostname that does not match. Your application generates a 400 after parsing: JSON that would not deserialise, a required field missing, a parameter of the wrong type.

The distinguishing signal is usually the body. A proxy's 400 comes with a plain, branded error page and nothing in your application logs; your application's 400 comes with a message you wrote, and a log line.

Common causes

  • Malformed JSON or a body that does not match the declared Content-Type.
  • A required parameter, header or field missing from the request.
  • Request headers exceeding the server's size limit — commonly an oversized cookie after a session bug.
  • An invalid or unexpected Host header, which many servers reject outright.
  • A URL containing characters that were never encoded, or a doubly-encoded path.
  • A client sending HTTP to a port expecting HTTPS, which some servers answer with a 400.

How to diagnose it

  1. Look for the request in your application log. If it is absent, the proxy or web server generated the 400 and the cause is at that layer.
  2. Read the response body — most application-level 400s name the field that failed.
  3. Replay the exact request with curl -v and compare it against one that works.
  4. If cookies are large, retry with them removed: header-size limits are a common and invisible cause.
  5. Check the proxy's own error log, which usually records the specific reason a request was rejected.

Whose fault is it? Usually the client's side

The request was at fault. The one case worth pausing on is when it started failing without the client changing: then something on the server side became stricter — a proxy upgrade, a new WAF rule, a lowered header limit.

What monitoring sees

A monitor returning 400 is nearly always misconfigured rather than detecting an outage: wrong body, wrong content type, a missing header. Uptimely records the status code and the response, so the specific 400 is visible on the check rather than being reported as a bare failure.

Questions

What is the difference between 400 and 422?

A 400 means the request could not be understood — bad syntax, malformed body, invalid headers. A 422 means it was understood perfectly and was semantically wrong, such as a valid JSON body with a field that fails validation.

Why did a request that worked yesterday start returning 400?

Usually something on the server side got stricter, or a header grew. A proxy upgrade, a new WAF rule, or a session cookie that has been accumulating data until it crossed the header-size limit are the three usual explanations.

One of the Uptimely HTTP and network error guides, written for the person who operates the server rather than the one refreshing the page. Something here read wrong to you? Email support@getuptimely.com.