---
title: "400 Bad Request Error: Causes and How to Fix It"
url: https://apyhub.com/blog/400-bad-request
author: ApyHub
published: 2026-10-20T10:33:08.508225Z
tags: [engineering]
---

# 400 Bad Request Error: Causes and How to Fix It

## Introduction

A **400 Bad Request** error means the server received your request but refused to process it because something in the request itself is wrong. The problem is on the client side: the URL, a header, a cookie or the request body. RFC 9110, the HTTP standard, describes it as a client error such as "malformed request syntax, invalid request message framing, or deceptive request routing" ([RFC 9110, section 15.5.1](https://www.rfc-editor.org/rfc/rfc9110#name-400-bad-request)).

The key rule: **sending the same request again will fail the same way.** Something has to change first.

Jump to what you need:

* [Seeing it in your browser?](#fix-a-400-error-in-your-browser) Four quick fixes.
* ["Request header or cookie too large"?](#400-request-header-or-cookie-too-large) Fix for users and for nginx.
* [Getting it from an API?](#why-an-api-returns-400-bad-request) The 6 common causes and a debugging checklist.

## Fix a 400 error in your browser

If a website shows "400 Bad Request" or Google shows "400. That's an error. Your client has issued a malformed or illegal request", try these in order:

1. **Check the URL.** A typo, a stray `%` or a character that was not encoded correctly is a frequent cause. Retype the address or open the site from its homepage.
2. **Clear cookies for that site.** A corrupted or oversized cookie is the other usual suspect. In Chrome, go to Settings → Privacy and security → Third-party cookies → See all site data and permissions, search for the site and delete its data.
3. **Clear the browser cache**, then reload.
4. **Try a private window or another browser.** If it works there, a browser extension or stored site data is the cause.

If the error only appears when you upload a file, the file may be larger than the site accepts. Try a smaller one.

## 400 Request Header or Cookie Too Large

This variant means the browser sent more cookie or header data than the server accepts.

**As a user:** delete cookies for that site (step 2 above). Sites that set many tracking or session cookies hit this limit over time.

**As the site owner on nginx:** nginx reads headers into buffers. A single header line larger than one buffer returns 400 ([nginx docs](https://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers)). The default is 4 buffers of 8 KB. Raise it in the `http` or `server` block:

```
large_client_header_buffers 4 16k;
```

Then reload nginx. A better long-term fix is to find which cookie keeps growing and cap it, since every request carries those bytes.

## Why an API returns 400 Bad Request

For developers, a 400 from an API almost always comes from one of six causes.

### 1. Invalid JSON in the body

A trailing comma, single quotes or an unescaped character breaks parsing. This body is invalid because of the last comma:

```json
{ "email": "ana@example.com", "plan": "pro", }
```

**Fix:** validate the payload with a JSON linter, or build it with `JSON.stringify()` or `json.dumps()` instead of string concatenation.

### 2. Missing or wrong Content-Type

Sending JSON without `Content-Type: application/json` makes many servers parse the body as form data, or not at all. Some return 415 Unsupported Media Type; many return 400.

**Fix:** set the header to match the body:

```bash
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"email":"ana@example.com"}'
```

### 3. A required field is missing or has the wrong type

`"age": "thirty"` where the API expects a number, or a missing `email`, fails validation. Some APIs return 422 for this; many return 400.

**Fix:** read the error body. Well-built APIs name the field. Then check it against the API documentation.

### 4. Query parameters that are not URL-encoded

Spaces, `&`, `#` or `+` inside a parameter value break the query string. `?q=salt & pepper` arrives as two parameters.

**Fix:** encode values with `encodeURIComponent()` or your HTTP client's params option, so `salt & pepper` becomes `salt%20%26%20pepper`.

### 5. Oversized or malformed headers

Large cookies, a long `Authorization` token, or a duplicated or invalid `Host` header can trigger a 400 before your code ever runs.

**Fix:** in Chrome, open DevTools → Application → Cookies and look for unusually large values on that domain, then delete or shorten them. In the Network tab, the request headers show how big the `Authorization` token is. A related limit: when the URL itself is too long, nginx returns 414 URI Too Long rather than 400, so a long query string is better sent as a POST body.

### 6. HTTP sent to an HTTPS port

nginx returns "400 Bad Request: The plain HTTP request was sent to HTTPS port" when a client or proxy sends plain HTTP to port 443.

**Fix:** use `https://` in the URL, or correct the proxy's upstream scheme.

## A 5-step checklist to debug any 400

1. **Read the response body, not only the status.** Most APIs explain the problem there.
2. **See the exact request that went out.** `curl -v` prints the method, headers and body on the wire. Your code may be sending something different from what you think.
3. **Reduce to the smallest request that fails.** Remove optional fields and headers one at a time until the error disappears. The last thing you removed is the cause.
4. **Compare with a request that works.** The official documentation example, or a request that succeeded yesterday, side by side with the failing one.
5. **Check what changed.** A new API version, a renamed field or a stricter validator explains many 400s that "came out of nowhere".

## What a real 400 looks like

Here is a request to ApyHub's [Email Validation API](https://apyhub.com/apyhub/service/verify-email-validity-and-deliverability) with one mistake: the field is named `mail` instead of `email`.

```bash
curl -X POST "https://api.eu.apyhub.com/apyhub/verify-email-validity-and-deliverability" \
  -H "apy-token: $APY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mail":"ana@example.com"}'
```

The API rejects it before doing any work:

```json
{
  "error": {
    "message": "Please provide the value for email",
    "code": 101
  }
}
```

The message names the missing field, so the fix takes seconds: rename `mail` to `email`. This is checklist step 1 in practice. The answer was in the response body, and the status code alone would not have told you.

To be honest about it, this response is not in the standard format we recommend further down (RFC 9457 problem details). It does the part that matters most, naming the field, and a standard shape would add a consistent `type` and `title` on top so clients can handle every error the same way.

## Why AI agents hit 400s so often

AI agents and coding assistants that write their own HTTP calls produce 400s in predictable ways:

* **Guessed field names.** The model writes `mail`, `email_address` or `userEmail` because it has seen all three in other APIs, exactly like the example above.
* **Wrong types.** Numbers sent as strings (`"limit": "10"`) and booleans as `"true"`.
* **Missing headers.** The body is valid JSON, but `Content-Type` is never set.
* **Stale documentation.** The model learned an older version of the API, before a field was renamed or made required.

An agent that receives a 400 often retries the same request, which fails the same way and burns tokens. Two things help: return error messages that name the field (see "If you build the API" below), and give agents ready-made tools with a fixed input schema instead of letting them build raw requests. Every endpoint in the [ApyHub catalog](https://apyhub.com/catalog) is available that way through [ApyHub MCP](https://apyhub.com/mcp), so Claude, Cursor or ChatGPT call a defined tool rather than improvising the payload. For the bigger picture, see [how AI agents use APIs](https://apyhub.com/blog/how-ai-agents-use-apis-a-beginner-s-guide).

## 400 vs other 4xx errors

| Code                       | Meaning                               | Typical cause                                  |
| -------------------------- | ------------------------------------- | ---------------------------------------------- |
| 400 Bad Request            | The request is malformed or invalid   | Broken JSON, bad parameters, oversized headers |
| 401 Unauthorized           | You are not authenticated             | Missing or expired token                       |
| 403 Forbidden              | You are authenticated but not allowed | Wrong permissions or scope                     |
| 404 Not Found              | The resource does not exist           | Wrong URL or deleted item                      |
| 405 Method Not Allowed     | The method is not supported here      | POST to a GET-only endpoint                    |
| 415 Unsupported Media Type | The body format is not accepted       | Wrong Content-Type                             |
| 422 Unprocessable Content  | The syntax is fine, the data is not   | Valid JSON with an invalid value               |
| 429 Too Many Requests      | You are rate limited                  | Too many calls too fast                        |

New to APIs? Start with [API fundamentals: what an API is and how to use one](https://apyhub.com/blog/api-fundamentals-what-an-api-is-and-how-to-use-one-without-writing-code).

## If you build the API: return 400s people can fix

A bare `400 Bad Request` with no body sends developers on a hunt. RFC 9457 defines a standard error format, `application/problem+json` ([RFC 9457](https://www.rfc-editor.org/rfc/rfc9457.html), July 2023). Return the field and the reason:

```json
{
  "type": "https://api.example.com/errors/validation",
  "title": "Invalid request body",
  "status": 400,
  "detail": "Field 'email' must be a valid email address.",
  "instance": "/users"
}
```

One clear `detail` line saves more support tickets than any documentation page.

## Reproduce and fix a 400 in Voiden

Debugging a 400 means sending the same request over and over with small changes. An API client makes that faster than editing curl commands.

[Voiden](https://voiden.md) is a free, open-source API client that works offline and stores each request as a plain Markdown `.void` file in your repository. That helps with 400s in three ways:

* **Requests are built from blocks** (endpoint, headers, auth, params), so you can edit or swap one block at a time and resend to isolate the cause.
* **The fixed request lives in Git** next to your code, so a teammate who hits the same 400 opens the working version instead of rebuilding it.
* **The same requests run headless in CI**, with deterministic exit codes, so a change that starts returning 400 fails the build before it reaches users.

[**Download Voiden free →**](https://voiden.md/download)

## Stop bad input before it becomes a 400

Many 400s come from user input that was never checked: an email address that cannot receive mail, a phone number in the wrong format, an IBAN with a wrong digit. Catching those at the form avoids a failed call further down the line.

The [data validation APIs on ApyHub](https://apyhub.com/catalog/data-validation) check these values before you use them, for example [email deliverability](https://apyhub.com/apyhub/service/verify-email-validity-and-deliverability), [phone numbers](https://apyhub.com/creightonnick0/service/validate-phone-number) and [IBANs](https://apyhub.com/quadlem/service/iban-validation). Every ApyHub API also returns the same `400 bad_request` error shape across the [catalog](https://apyhub.com/catalog), so your error handling works the same for all of them.

[**Browse the validation APIs →**](https://apyhub.com/catalog/data-validation)

## Conclusion

A 400 Bad Request always means the request needs to change before it can succeed. In the browser, check the URL and clear the site's cookies. On an API, read the error body, inspect the raw request with `curl -v`, and cut it down until you find the broken field, header or encoding. If you run the server, return problem details so the next developer fixes it in minutes.

[**Start free on ApyHub, no card required →**](https://apyhub.com/)

## FAQ

### What does 400 Bad Request mean?

The server refused to process the request because something in it is wrong: the URL, a header, a cookie or the body. It is a client-side error.

### How do I fix a 400 Bad Request error in Chrome?

Check the URL for typos, delete the site's cookies, clear the cache, and try a private window. One of these fixes most browser 400s.

### Is a 400 error my fault or the website's?

It is triggered by the request your browser or app sent. Sometimes the cause is data the site stored itself, such as an oversized cookie, so clearing site data fixes it.

### What is the difference between 400 and 422?

400 means the request is malformed or invalid. 422 means the syntax is correct but a value fails validation. Many APIs use 400 for both.

### What does "Request Header or Cookie Too Large" mean?

The browser sent more header or cookie data than the server accepts. Delete the site's cookies; on nginx, raise `large_client_header_buffers`.

### Is a 400 error permanent?

No. It repeats until the request changes. Fix the URL, cookie, header or body and it goes away.

### How can I test API requests to find the cause of a 400?

Use `curl -v` to see the raw request, or an API client like [Voiden](https://voiden.md) to resend the request with one change at a time and keep the working version in Git.

### Can AI agents cause 400 errors?

Yes. Agents that build request payloads themselves often send wrong field names or types. Calling ready-made endpoints through [ApyHub MCP](https://apyhub.com/mcp) keeps the request shape fixed, because each tool has a defined input schema.

## About ApyHub

[ApyHub](https://apyhub.com/) is a curated API catalog and the trusted operational layer between your application and the services it depends on. One subscription, billed in atoms, covers the whole [catalog](https://apyhub.com/catalog) of over 1,500 endpoints and capabilities, and it keeps growing. Every service is evaluated before it is listed and carries machine-readable certification covering GDPR, SOC 2 and ISO 27001. Every endpoint is MCP-ready by default. ApyHub runs dedicated EU and US regions and serves more than 65,000 developer workspaces every month. Start on the free tier with no card, or [publish your own API on ApyHub](https://apyhub.com/api-provider).

## Sources

* IETF, [RFC 9110: HTTP Semantics, section 15.5.1](https://www.rfc-editor.org/rfc/rfc9110#name-400-bad-request) (June 2022)
* IETF, [RFC 9457: Problem Details for HTTP APIs](https://www.rfc-editor.org/rfc/rfc9457.html) (July 2023)
* MDN Web Docs, [400 Bad Request](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/400)
* nginx, [large_client_header_buffers](https://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers)
