Geonode logo
Website and server errors

How to Fix a 400 Bad Request Error

Tell a cookie problem from a broken URL or body, then fix the part the server rejected.

Updated

TL;DR

400 Bad Request means the website's server could not or would not read your request, because something in it, such as a URL, header, cookie or body, was malformed. Sending it again unchanged fails the same way, so in a browser clear that site's cookies first.

What a 400 looks like in each server and client

Server pages often name the reason; clients print the code and little else, so read the body too.

WhereWhat you see
nginx, one header line over its buffer400 Bad Request Request Header Or Cookie Too Large nginx
nginx, http:// sent to an HTTPS port400 Bad Request The plain HTTP request was sent to HTTPS port nginx
Apache httpd, Cookie over LimitRequestFieldSizeBad Request Your browser sent a request that this server could not understand. Size of a request header field exceeds server limit.
Flask (Werkzeug 3.1 and earlier)Bad Request The browser (or proxy) sent a request that this server could not understand.
Python requests (raise_for_status)requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://example.com/api/search
curl with --failcurl: (22) The requested URL returned error: 400
Python urlliburllib.error.HTTPError: HTTP Error 400: Bad Request

Why this happens

Your request broke the server's rules for size or format, so it stopped reading.

Browsers attach a site's cookies to every request, and RFC 6265 asks them to hold at least 50 cookies of 4,096 bytes per domain, far more than nginx or Apache accept in one header line by default.

Diagnose your 400 first

Each check rules out one suspect: cookies, the route, the body or server limits.

  • Open the page in an Incognito window; if it loads there, data your normal profile sends, such as that site's cookies, caused the 400.

  • Read the error page; text such as Request Header Or Cookie Too Large names the part of the request the server refused.

  • With curl -v through your proxy to an https:// URL, find the 400; under CONNECT, the proxy refused; after the proxy's 200, the site did.

  • Print the response body as well as the status; if it names a field or a JSON parse error, the server rejected your body.

  • If you run the site, lower its error log to info; AH00561 in Apache or too long header line in nginx means an oversized header.

Solutions ranked by effectiveness

Pick the card that matches where you saw the 400: your browser, your own code or your server.

  1. Most common fix

    Delete the site's cookies in your browser

    Applies to browser visitors. Removing one site's stored data may sign you out of that site, while every other site keeps its cookies.

    1. In Chrome, open More > Settings > Privacy and security > Third-party cookies.

    2. Select See all site data and permissions, then search for the site's name.

    3. Select Delete next to the site, confirm, then reload the page.

  2. For developers

    Encode the URL and match the body type

    Applies when your code builds the request itself. Let an encoder build the query string and a serializer build the JSON, and label the body with a matching Content-Type.

    import json, urllib.error, urllib.parse, urllib.request
    
    query = urllib.parse.urlencode({"q": "red shoes", "city": "São Paulo"})
    url = "https://example.com/api/search?" + query
    body = json.dumps({"name": "Ana", "tags": ["new"]}).encode()
    req = urllib.request.Request(url, data=body, method="POST",
                                 headers={"Content-Type": "application/json"})
    try:
        with urllib.request.urlopen(req, timeout=30) as res:
            print(res.status, res.read(300).decode())
    except urllib.error.HTTPError as err:
        print(err.code, err.read(300).decode(errors="replace"))
  3. Site owners

    Size header buffers for your real cookies

    Applies when your nginx or Apache logs oversized headers from ordinary visitors; raise the per-line limit.

    1. nginx: set large_client_header_buffers 4 16k; in the http or server block.

    2. Apache: raise LimitRequestFieldSize from 8190 in the server config or first virtual host.

    3. Run nginx -t or apachectl configtest, then reload the server.

Stop the 400 from coming back

Habits for request code and for servers, so a malformed request is caught before it ships.

  1. Let your HTTP library set Host and Content-Length; RFC 9112 makes servers reject two Host lines or a bad length.

  2. Write https:// for every port that serves TLS, such as 443; nginx answers plain http:// there with 400.

  3. Return a short reason in each 400 body, as RFC 9110 advises, so callers can fix their own request.

  4. Keep session data on the server and only an ID in the cookie, so Cookie headers stay small.

Let the dashboard build your usernameConfigure a location in Geonode's dashboard, and it shows the updated username to copy.
Try residential proxies

Related errors

Learn more

FAQ

The server refused to process your request because it looked wrong: bad syntax, broken framing such as a wrong Content-Length, or misleading routing. It is a client-error code, so change the request instead of waiting.

It is a 400 your client received while a proxy was set. For HTTPS pages, the proxy sent it only if it refused to open the tunnel; otherwise the site did. Geonode's documented proxy error codes do not include 400.

One header line, such as Cookie, outgrew a single large_client_header_buffers buffer, 8 KB by default. nginx sends this page with status 400, though its source calls the case 494; a request line over the limit gets 414 instead.

It is the default 400 text of Werkzeug 3.1 and earlier, the library under Flask. Flask sends it when code reads a form field the request lacks, or when get_json() cannot decode the body.

HTTP.sys, the Windows component that answers for IIS, rejected the Host header, for example one carrying https:// or a path, or a name the site does not answer to. httperr.log records the reason as Hostname.

.NET's HttpWebRequest, which WebClient also uses, throws a WebException with this message for any 400 reply. The server's explanation sits in ex.Response; read its stream before changing the request.

Proxy errors that name the field

Invalid Geonode username flags get a 403 with details about which field caused the issue.