Last tested: October 22, 2026 · By Alex
A 400 Bad Request error means the server received your request but refused to process it because something in the request itself is malformed, oversized, or invalid. The server is up. The problem is what the browser, app, or script sent.
In practice, most 400 errors I see on real sites come from a short list: bloated or corrupted cookies, a broken URL, oversized headers, an invalid JSON body sent to an API, or a proxy layer (Cloudflare, a load balancer, NGINX) that rejects something the origin would have accepted.
Quick Fix
- Reload the page and check the URL for typos, stray
%characters, spaces, or unencoded symbols. - Clear cookies for the affected domain only (not your whole browser).
- Try the same URL in a private/incognito window.
- Clear the browser cache and DNS cache.
- If uploading a file, try a smaller file to rule out a size limit.
- Disable browser extensions that modify requests (ad blockers, header editors, VPN extensions).
- If you run the site, check the web server error log at the exact time of the error.
- For APIs, validate the JSON body and the
Content-Typeheader.
What Is 400 Bad Request?
400 Bad Request is an HTTP client error status code. It tells the client that the server cannot or will not process the request because of something perceived as a client error: invalid syntax, invalid framing, a deceptive request, or a request the server simply cannot parse.
It is worth separating it from similar codes:
- 401 Unauthorized means authentication is missing or invalid.
- 403 Forbidden means the request is understood but access is denied.
- 404 Not Found means the request is valid but the resource does not exist.
- 413 Content Too Large means the body is too big.
- 414 URI Too Long and 431 Request Header Fields Too Large are more specific versions of “your request is too big”.
Many servers do not use the specific codes. NGINX, for example, returns 400 Bad Request — Request Header Or Cookie Too Large instead of a 431. So a 400 is often a generic catch-all for a more specific problem.
Why 400 Bad Request Happens
1. Oversized or Corrupted Cookies
This is the most common cause on WordPress and WooCommerce sites. Plugins, analytics tools, A/B testing scripts, and session handlers keep adding cookies. Once the combined Cookie header exceeds the server buffer, the request is rejected before it reaches PHP. A corrupted cookie value with invalid characters can trigger the same result.
2. Malformed URL
Unencoded characters, a lone % sign, double-encoded strings like %2520, or illegal characters in the path can make the server refuse the request. This often happens when links are copied from email clients or generated by broken code.
3. Headers That Are Too Large
Long Authorization tokens (for example big JWTs), large Referer values, or many custom headers can exceed server limits. Apache and NGINX both have hard limits on individual header lines and on total header size.
4. Invalid Request Body
APIs return 400 when the JSON is invalid, a required field is missing, a value has the wrong type, or the Content-Type header does not match the body. The WordPress REST API returns rest_invalid_param or rest_invalid_json with a 400 status in these cases.
5. Plain HTTP Sent to an HTTPS Port
If something sends plain HTTP to port 443, NGINX returns 400 Bad Request — The plain HTTP request was sent to HTTPS port. This usually points to a misconfigured proxy, load balancer, or a listen 443 directive without ssl.
6. Proxy or CDN Mismatch
Cloudflare, load balancers, and reverse proxies can rewrite or add headers. If the origin receives a Host header it does not recognize, duplicate headers, or a bad X-Forwarded-* chain, it may answer with 400.
7. Stale DNS or Cache Data
Less often, a browser or OS keeps outdated DNS or cached redirects, and the request lands on the wrong server or with the wrong host name. That server then rejects it.
How to Fix 400 Bad Request Step by Step
1. Check the URL
Look at the address bar carefully. Remove tracking parameters, fix typos, and look for characters like %, {, }, |, or spaces. If the URL came from a link in an email, try opening the page from the site’s navigation instead.
2. Clear Cookies for the Site
In Chrome, click the icon left of the address bar, open Cookies and site data, and delete the cookies for that domain. In Firefox, use Settings → Privacy & Security → Cookies and Site Data → Manage Data. If the error disappears, the cookie size or a broken cookie value was the cause.
3. Test in a Private Window or Another Browser
A private window starts without cookies and without most extensions. If the page loads there, the problem is local to your browser profile.
4. Flush DNS
Clear the local DNS cache to rule out stale records:
# Windows
ipconfig /flushdns
# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
# Linux (systemd-resolved)
sudo resolvectl flush-caches
5. Reproduce the Request with curl
curl removes the browser from the equation. Compare a clean request with one that includes your real cookies:
curl -I https://example.com/page/
curl -I -H "Cookie: $(cat cookies.txt)" https://example.com/page/
If the clean request returns 200 and the one with cookies returns 400, you have found the cause. For APIs, send the exact payload:
curl -i -X POST https://example.com/wp-json/wp/v2/posts \
-H "Content-Type: application/json" \
-u "user:application-password" \
-d '{"title":"Test","status":"draft"}'
Read the response body. The WordPress REST API and most frameworks explain exactly which parameter failed.
6. Check Server Logs
On the server, look at the error log at the timestamp of the failure:
# NGINX
sudo tail -f /var/log/nginx/error.log
# Apache (Debian/Ubuntu)
sudo tail -f /var/log/apache2/error.log
# Apache (RHEL/AlmaLinux)
sudo tail -f /var/log/httpd/error_log
Messages such as client sent too long header line (NGINX) or Size of a request header field exceeds server limit (Apache) confirm a header size issue. On shared hosting, the logs are usually under Metrics → Errors in cPanel or in the hosting panel’s log section.
7. Validate API Payloads
Run JSON through a validator or jq before sending it:
echo '{"title":"Test",}' | jq .
# parse error: Expected another key-value pair
Make sure Content-Type: application/json is set when sending JSON, and multipart/form-data with a correct boundary when uploading files.
8. Review Recent Changes
If the error started after a plugin update, a new CDN rule, or a server config change, roll that change back first. That is faster than debugging blind.
Advanced Troubleshooting
Increase Header Buffers in NGINX
If logs show header or cookie size problems and you control the server, raise the buffer in the http or server block:
http {
client_header_buffer_size 4k;
large_client_header_buffers 8 32k;
}
Then test and reload:
sudo nginx -t && sudo systemctl reload nginx
Raise the values carefully. Huge limits mask the real problem, which is usually a plugin setting too many cookies.
Increase Header Limits in Apache
In the main Apache config or the virtual host (these directives do not work in .htaccess):
LimitRequestFieldSize 16380
LimitRequestLine 16380
sudo apachectl configtest && sudo systemctl reload apache2
Fix “Plain HTTP Request Was Sent to HTTPS Port”
Make sure the HTTPS server block actually enables TLS:
server {
listen 443 ssl;
http2 on;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
}
Also check that your load balancer forwards to the right port with the right protocol.
Check for Bad Rewrite Rules in .htaccess
A rewrite rule that builds an invalid URL can produce 400 responses. Temporarily rename .htaccess and restore the default WordPress block to test:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
WordPress-Specific Causes
- Cookie bloat: WooCommerce, membership plugins, and marketing tools can stack cookies. Audit them in DevTools → Application → Cookies and remove plugins you no longer need.
- REST API requests: Gutenberg, page builders, and headless frontends call
/wp-json/. A 400 there usually comes with a JSON error code that names the problem. - admin-ajax.php: A 400 with the body
0fromadmin-ajax.phpmeans no handler is registered for theactionparameter. Usually a deactivated plugin or a missingwp_ajax_nopriv_hook for logged-out users. - Security plugins: Some firewall plugins return 400 for requests they consider suspicious. Check their logs before changing server settings.
The Cloudflare Angle
If the error page shows Cloudflare branding, check whether Cloudflare or the origin generated it. A Cloudflare-generated 400 often mentions header or cookie size: Cloudflare limits request headers to about 32 KB total and 16 KB per header. Your origin may have lower limits, in which case the response comes from your server and Cloudflare just passes it through.
Useful checks:
- Pause Cloudflare temporarily or test the origin directly with
curl --resolve example.com:443:ORIGIN_IP https://example.com/. - Review Security → Events for blocked requests and the rule that matched.
- Check Transform Rules and Workers that modify headers.
Prevention Tips
- Keep the number and size of cookies small. Remove unused tracking scripts.
- URL-encode all user input and dynamic parameters in links.
- Validate API payloads on the client before sending them.
- Keep header buffers on all layers (CDN, load balancer, NGINX, Apache) consistent so one layer does not reject what another accepts.
- Test config changes with
nginx -torapachectl configtestbefore reloading. - Monitor 4xx rates in logs so a new spike after a deployment gets noticed quickly.
When to Contact Support
Contact your host or the site owner if the error appears in every browser and on every device, clearing cookies does not help, and you have no access to server configuration. Send them the exact URL, the time of the error with your time zone, and the response headers from curl -I. On shared hosting, header buffer limits can only be changed by the provider.
Frequently Asked Questions
The server received the request but could not process it because something in the request is invalid: a malformed URL, oversized or corrupted cookies, headers that are too large, or an invalid request body.
It is a client-side error code, so start with your browser: check the URL, clear the site’s cookies, and try a private window. If it happens for everyone, the cause is on the server, CDN, or proxy configuration.
When the combined Cookie header grows past the server’s header buffer, or a cookie value is corrupted, the server rejects the request. Deleting the site’s cookies makes the request small and valid again.
Reduce cookies first. If you control the server, raise large_client_header_buffers (for example 8 32k) in the http or server block, then run nginx -t and reload NGINX.
Final Thoughts
A 400 Bad Request is the server saying “I can’t read what you sent.” Start on the client side: check the URL, clear site cookies, and retest in a private window. If you own the site, reproduce the request with curl and read the error log. That combination finds the cause in most cases within minutes, whether it is cookie bloat, a broken API payload, or a mismatched proxy layer.