Skip to content
RU
← All articles

400 Bad Request: How to Fix It in Chrome, nginx and APIs

A browser showing a 400 error with a very long URL in the address bar

A 400 Bad Request means the server rejected your request as malformed before any page or API code ran. In a browser the usual culprit is an oversized or corrupted cookie for that one site; in an API it is invalid JSON, a wrong Content-Type or a header that exceeds the server's size limit.

Because the refusal happens at the HTTP parsing layer — nginx, Apache, IIS, a CDN or a load balancer — the fix is rarely in the application the request was aimed at. Below: what the standard says, the exact error strings each server prints, a cause-by-cause table, step-by-step fixes for Chrome, Edge, Firefox and Safari, and the developer checklist for nginx, Postman and REST APIs.

What HTTP 400 Bad Request means

Status 400 Bad Request belongs to the 4xx class of client errors. Per RFC 9110, §15.5.1, the server returns 400 when it "cannot or will not process the request due to something that is perceived to be a client error" — for example, malformed request syntax, invalid request message framing, or deceptive request routing.

The key word is "client". Unlike 5xx errors, where the server is at fault, a 400 tells you: "I am working fine, but your request is assembled incorrectly." So the first diagnostic step is to figure out what exactly is wrong in the request — and which hop in the chain (CDN, reverse proxy, application) refused it.

What a 400 response looks like

HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=utf-8
Connection: close

<html>
  <head><title>400 Bad Request</title></head>
  <body><h1>Bad Request</h1></body>
</html>

The body text is the most useful clue you get. Different layers word it differently, and the wording tells you who rejected the request:

Message on the pageWho sends itWhat it actually means
400 Bad Request — Request Header Or Cookie Too Largenginx (internally status 494)One header line or the whole header block did not fit into large_client_header_buffers; almost always a bloated Cookie or a long Authorization token
400 Bad Request — The plain HTTP request was sent to HTTPS portnginx (internally 497)Plain http:// sent to a port that expects TLS, e.g. http://example.com:443/ or a proxy misconfigured to talk HTTP to an HTTPS upstream
400 Bad Request — No required SSL certificate was sentnginx (internally 496)The server requires a client certificate (mutual TLS) and the browser or client did not present one
Size of a request header field exceeds server limit.Apache httpdA header is longer than LimitRequestFieldSize (8190 bytes by default)
Bad Request - Request Too Long. HTTP Error 400. The size of the request headers is too long.IIS / Windows HTTP.sysHeaders exceed the HTTP.sys limits MaxFieldLength / MaxRequestBytes
Bad Request - Invalid HostnameIIS / HTTP.sysThe Host header does not match any binding on the server
JSON body such as {"error":"invalid_request"}Your API or frameworkThe request parsed as HTTP, but the application rejected its body or parameters

If the page is a bare nginx or IIS error and not your site's own design, the application never saw the request — look at limits and proxies, not at your code. For the standard's full list of neighbors, see the complete HTTP status code reference and the MDN reference for status 400.

What is the root cause of a 400 Bad Request?

Although a 400 is formally the client's "fault", server configuration can provoke it too (for example, overly strict header-size limits). Here is a summary table of typical causes.

CauseSideWhat happensHow to fix
Corrupted or oversized cookiesClientBrowser sends stale/broken cookies, header exceeds the limitClear the site's cookies
Malformed request syntaxClientBad request line, stray characters, broken framingCheck how the request is built in code
URL or headers too longClient + ServerURL/header length exceeds the server limitShorten the URL, raise nginx buffers
Wrong Content-Type / broken JSONClientBody does not match the declared type, JSON errorValidate JSON, set the correct header
Invalid characters or bad percent-encoding in the URLClientA raw space, a lone % or a copy-pasted link with hidden characters breaks the request lineRe-type the address, encode query values
Missing or duplicate Host headerClientRFC 9112, §3.2 requires a 400 when an HTTP/1.1 request has no Host or more than oneFix the client or the proxy that rewrites headers
Plain HTTP to an HTTPS portClient + ServerA TLS port receives unencrypted HTTPUse https://, fix proxy_pass scheme
Strict header limitsServerlarge_client_header_buffers is too smallRaise the limits in the config

Corrupted cookies — cause number one

The most common cause of a 400 for ordinary users is "bloated" or corrupted cookies. When the total cookie size exceeds the server's buffer limit (usually 4-8 KB), the server aborts the request with a 400. Symptom: the error appears on only one site, while the same site opens fine in incognito mode.

Cookies bloat for mundane reasons: an analytics or A/B-testing script that writes a new cookie on every visit, a single sign-on flow that stacks session cookies for several subdomains on the parent domain, or an app that stores a whole JSON object or a long JWT in a cookie. Every request to that domain carries all of them, so the header keeps growing until it crosses the limit. On the developer side, keep cookies small and scoped — the flags that control scope are covered in our guide to cookie security flags.

Broken JSON and wrong Content-Type

When working with an API, a 400 is often caused by an invalid request body. If you declared Content-Type: application/json but sent invalid JSON, the server responds with 400.

POST /api/v1/orders HTTP/1.1
Host: example.com
Content-Type: application/json

{ "name": "John", "amount": }   <-- missing value after "amount"

Other body errors that end the same way: a trailing comma after the last field, single quotes instead of double quotes, a JSON body sent with Content-Type: application/x-www-form-urlencoded, or a multipart/form-data body whose boundary does not match the one declared in the header.

Does a 400 error mean the site is down?

No. A 400 is proof the server is up: it received your request, parsed it far enough to find a problem, and answered. A site that is down produces a timeout, a connection refused, or a 5xx such as 502 or 503. If a site shows 400 to you but loads for everyone else, the problem is in your request — almost always cookies. If it shows 400 to everyone, the site's own configuration (a proxy, a CDN rule, a header limit) is broken.

The same applies to 400 errors on services you do not run, whether a streaming platform such as Kick, a bank or a SaaS dashboard: clear that site's data first; if the error persists in a clean browser, only the service's operators can fix it.

Is a 400 error permanent?

Not in the sense a 404 or 410 can be. The same broken request will keep getting 400 — resending it unchanged achieves nothing — but the moment the request changes (cookies cleared, URL fixed, body corrected, server limit raised), the error goes away. This is why a plain refresh rarely helps while deleting one site's cookies often does.

How to fix a 400 error as a user

If you hit a 400 as a site visitor, try these in order:

  • Clear this site's cookies — in browser settings, delete data for the specific domain.
  • Clear the cache and reload the page (Ctrl+F5 / Cmd+Shift+R).
  • Check the URL — remove stray characters, trim an overly long link.
  • Open the site in incognito mode — if it works, the problem is cookies/cache in your main profile.
  • Disable extensions that may interfere with requests.

How to fix 400 Bad Request on Google Chrome

  1. Open the failing site, press F12 to open DevTools, go to the Application tab, select Storage and click Clear site data. This removes cookies, local storage and cache for that origin only.
  2. Alternatively, type chrome://settings/content/all in the address bar, search for the domain and delete its data. Check the parent domain too: cookies set on .example.com are sent to shop.example.com.
  3. Reload the page. If the 400 is gone, bloated cookies were the cause.
  4. Still failing? Open a Guest window or disable extensions at chrome://extensions — header-modifying and privacy extensions can inject or rewrite headers.

Other browsers: in Edge, go to Settings → Cookies and site permissions → Manage and delete cookies and site data → See all cookies and site data; in Firefox, Settings → Privacy & Security → Cookies and Site Data → Manage Data; in Safari on macOS, Settings → Privacy → Manage Website Data. Remove only the affected domain. For full cache clearing steps per browser, see how to clear browser cache.

Why the same request fails in one browser but not another

If a 400 reproduces in Chrome but not in Firefox or incognito, the culprit is almost always profile-bound state: accumulated cookies, extensions that rewrite headers, or a stale cached request. Browsers store cookies independently, so a "bloated" set in one profile easily exceeds the server buffer while a clean profile stays under the limit. That is also why clearing a specific site's data is the fastest cure.

How to fix a 400 error as a developer

If your own server returns the 400, check request construction and limits. When sending JSON, always validate the body and set the correct header:

curl -v -X POST https://example.com/api/v1/orders \
  -H "Content-Type: application/json" \
  -d '{"name":"John","amount":100}'

The -v flag in curl shows both the request headers you sent and the response you received — it is the best way to see what actually reached the server. To validate a body before sending it, run python3 -m json.tool body.json or jq . body.json: both print the exact line and column of a syntax error.

If the error is caused by large headers (for example, a long JWT in a cookie or the Authorization header), raise the buffers in nginx:

http {
    large_client_header_buffers 4 16k;
    client_header_buffer_size   16k;
}

The nginx defaults are client_header_buffer_size 1k and large_client_header_buffers 4 8k: no single header line may exceed one large buffer (8 KB), and the whole header block must fit into four of them. Put the directives at the http level — per the large_client_header_buffers documentation, a value set in a server block may be ignored in favor of the default server's. Then test and reload:

sudo nginx -t && sudo systemctl reload nginx

You can reproduce the error on purpose to confirm the diagnosis and the fix — send a 9 KB cookie:

curl -s -o /dev/null -w '%{http_code}\n' \
  -H "Cookie: test=$(head -c 9000 /dev/zero | tr '\0' a)" \
  https://example.com/

On a default nginx this prints 400; after raising the buffers to 16k it returns your normal status. Raising limits treats the symptom, though. The real fix is to stop the cookie growth: find which cookie is large in DevTools → Application → Cookies, and move big payloads to server-side sessions.

Other servers have their own knobs. Apache: LimitRequestFieldSize 16380 in the server or virtual host config. IIS: the registry values MaxFieldLength and MaxRequestBytes under HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters, followed by a restart of the HTTP service. Gunicorn: --limit-request-field_size and --limit-request-line. Node.js answers oversized headers with 431 Request Header Fields Too Large rather than 400 and is tuned with --max-http-header-size. Remember that every hop has a limit: raising it on nginx does nothing if the app server behind it still rejects the header.

400 Bad Request nginx: reading the log

nginx logs client errors such as oversized headers at the info level, so with the default error level the error log stays silent. Temporarily lower it:

error_log /var/log/nginx/error.log info;

Reproduce the request and look for lines like client sent too long header line, client sent invalid request or client sent plain HTTP request to HTTPS port. The access log confirms that the status came from nginx itself: a 400 with a tiny response size and no upstream timing means the request never reached the backend. More on where logs live and how to read them in our nginx logs guide.

400 Bad Request in Postman

Postman sends exactly what you configure, so a 400 there is almost always one of these:

  • Body type mismatch. In Body → raw, the dropdown must say JSON, not Text; otherwise the request goes out as text/plain and a JSON API rejects it.
  • A manual Content-Type header in the Headers tab that overrides the one Postman sets automatically.
  • Unresolved variables. A {{baseUrl}} or {{token}} without a value in the active environment is sent literally.
  • Required parameters missing from the query string or body.

Open the Postman Console to see the raw request that was actually sent, headers included, and compare it with a working curl -v call.

400 Bad Request in a REST API

If you build the API, make every 400 explain itself. A bare "Bad Request" forces clients to guess; a structured body tells them what to change. RFC 9457 defines a standard format for this:

HTTP/1.1 400 Bad Request
Content-Type: application/problem+json

{
  "type": "https://example.com/problems/invalid-body",
  "title": "Request body is not valid JSON",
  "status": 400,
  "detail": "Unexpected token '}' at line 1, column 29"
}

Log the reason on the server side as well, with a request ID the client can quote. Never echo secrets, tokens or full request bodies back in the error.

How to diagnose the source of a 400

To find where the request breaks, work from simple to complex:

  1. Reproduce the error in incognito — rule out cookies/cache.
  2. Replay the request with curl -v — see the exact headers and body.
  3. Compare a working request against the failing one, header by header.
  4. Check server logs — nginx writes the reason (e.g. "client sent too long header").
  5. Walk the chain: bypass the CDN (request the origin directly, if you are allowed to), then the reverse proxy, and see at which hop the 400 appears.

400 versus other 4xx codes: don't mix them up

A 400 is the "generic" answer to a malformed request. But it has more specific neighbors, and a well-designed server returns those instead. Knowing the difference speeds up diagnosis.

StatusMeaningTypical fix
400 Bad RequestThe request syntax is broken and the server cannot parse it at allFix cookies, headers, URL or body
401 UnauthorizedThe syntax is fine, but authentication credentials are missing or invalidLog in again, send a valid token
403 ForbiddenYou are authenticated, but lack rights to the resourceCheck permissions, WAF rules
413 Content Too LargeThe request body exceeds the server limitRaise client_max_body_size or send less
414 URI Too LongThe request line is too long; nginx and Apache send this, not 400, for an overlong URLMove data from the query string into a POST body
422 Unprocessable ContentThe syntax is fine, but the data fails business validation (e.g. a badly formatted email)Correct the field values
431 Request Header Fields Too LargeThe precise code for oversized headers; many servers send 400 insteadSame as the cookie fix above

An important nuance: some frameworks return 400 where 422 would be more accurate. If you build an API, try to separate "couldn't parse the request" (400) from "parsed it, but the data is logically invalid" (422) — it makes debugging much easier for your API's clients. Body-size failures have their own article: HTTP 413 Request Entity Too Large.

How to check the server response

The fastest way to see the status code and the full set of headers is a free HTTP header and response code checker on enterno.io. Enter an address and instantly see the status, request and response headers, redirects, and security hints. This helps you tell a client-side 400 from a server-side 5xx. When diagnosing an API, compare the headers of a working request against the failing one — the difference is usually obvious at a glance: an extra header, a wrong Content-Type, or a missing required parameter.

Two more checks help when the 400 is on your own site:

  • Technology detector — shows whether nginx, Apache, IIS or a CDN such as Cloudflare answers, so you know whose limits and error page you are dealing with.
  • Redirect checker — a redirect chain that bounces between http:// and https:// or across subdomains can hand the browser to a port or host that answers 400.

If the checker gets a 200 while your browser gets a 400, the site is fine and your browser's stored cookies are the problem.

To understand response codes more deeply, read the complete HTTP status code reference, plus breakdowns of neighboring errors: 403 Forbidden and 404 Not Found. If your 400 is cookie-related, see our guide to cookie security flags.

FAQ

How do you fix a 400 bad request?

As a visitor, delete that site's cookies and cached data, check the URL for stray characters, and retry in a private window. As a developer, replay the request with curl -v, validate the JSON body and Content-Type, and check whether a header exceeds the server's limit.

Is 400 Bad Request an error on my side or the site's side?

Formally, status 400 belongs to the 4xx class of client errors: the server reports that the request is malformed. But server settings can provoke it too — for example, overly strict header-size limits. Start diagnosis by clearing cookies and cache, then check how the request is built.

Why does a 400 appear on only one site?

Almost certainly corrupted or bloated cookies for that specific domain are to blame. Each site stores its cookies separately, so the problem is isolated. Clear that site's data in browser settings or open it in incognito mode — if everything works there, cookies or cache are the cause.

How do I fix a 400 when posting JSON to an API?

Make sure the request body is valid JSON with no trailing commas or missing values, and that the Content-Type: application/json header matches the actual format. Run the request through curl -v to see what actually leaves for the server, and validate the JSON with any linter before sending.

Why does a long URL cause a 400?

Servers limit the length of the request line and the size of headers, usually to a few kilobytes. nginx and Apache answer an overlong URL with 414, but some servers and proxies collapse it into a generic 400, and long headers produce 400 on most stacks. The user fix is to shorten the link; the developer fix is to raise the limit or move data into the POST body.

Does reloading the page help with a 400 error?

A plain refresh rarely helps because the cause is usually stored data. A hard reload with a cache purge (Ctrl+F5) plus deleting the site's cookies is far more effective. If the error disappears afterward, client data was to blame; if not, the problem is in the request itself or the server configuration.

Check your website right now

Check your site's HTTP status →
More articles: HTTP
HTTP
404 Not Found Error: Causes and Fixes for Chrome, nginx, Apache
15.04.2026 · 1 967 views
HTTP
HTTP Methods Explained: GET, POST, PUT, DELETE and Beyond
16.03.2026 · 978 views
HTTP
Server-Sent Events vs WebSockets: Which to Use for Realtime
16.03.2026 · 974 views
HTTP
The Complete HTTP Request Lifecycle: From URL to Rendered Page
16.03.2026 · 892 views