What Is a 400 Bad Request Error and How Do You Fix It?
A 400 Bad Request is an HTTP/1.1 client error status code defined in RFC 9110 that signals the server received a request it cannot or will not process because the request itself is malformed. Unlike 5xx errors, which originate on the server side, a 400 error places the fault squarely on the client — meaning the problem lies in the request being sent, not in the server's ability to respond.
In practical terms, a 400 error fires before the server even attempts to fulfill the request. The server parses the incoming HTTP message, detects something structurally or semantically invalid — a corrupt header, a malformed URI, an oversized payload, a bad cookie — and immediately returns 400 Bad Request rather than proceeding. Knowing this distinction is the fastest path to correct diagnosis.
What the 400 Status Code Actually Means at the Protocol Level
HTTP operates on a strict request-response contract. Every request must conform to the grammar defined in the HTTP specification. When a client sends a message that violates this grammar, the server is both permitted and expected to reject it with a 400 response.
The server does not log a 400 as its own failure. It logs it as a rejected client request. This is why blindly restarting a server or clearing a CDN cache rarely fixes a genuine 400 — the root cause is almost always in the request construction.
Common browser-rendered variants of this error include:
400 Bad RequestHTTP Error 400Bad Request — Invalid URL400. That's an error. Your client has issued a malformed or illegal request.400 Bad Request. The server cannot or will not process the request due to something that is perceived to be a client error.
All of these map to the same underlying HTTP status code. The phrasing differs by server software (Apache, Nginx, IIS, Cloudflare) and application framework.
Root Causes of a 400 Bad Request Error
Understanding the precise trigger is essential before attempting any fix. The causes fall into two categories: client-side and server-side misconfiguration.
Client-Side Causes
Malformed or improperly encoded URL
A URL containing unencoded spaces, illegal characters, or broken percent-encoding sequences will be rejected immediately. The HTTP specification requires that all characters outside the unreserved set (A–Z, a–z, 0–9, -, _, ., ~) be percent-encoded before transmission.
Corrupted or oversized cookies
Cookies are transmitted in the Cookie request header. If a cookie value is malformed, exceeds the browser's per-cookie size limit (typically 4096 bytes), or contains characters that violate RFC 6265, the server may reject the entire request. This is one of the most frequently overlooked causes of intermittent 400 errors on sites a user has previously visited without issue.
Invalid or missing required request headers
Some APIs and web applications enforce strict header validation. A missing Content-Type on a POST request, a malformed Authorization header, or an Accept header with an unsupported media type can all trigger a 400.
Oversized request payload
Web servers and reverse proxies enforce maximum body size limits. Nginx uses client_max_body_size (default: 1 MB); Apache uses LimitRequestBody. Exceeding these thresholds produces a 400 or 413 response depending on configuration.
Stale or incorrect DNS cache
While DNS resolution failures typically produce connection errors rather than HTTP 400s, a poisoned or stale DNS cache that routes a request to the wrong server — one that does not recognize the Host header — can result in a 400 being returned by the wrong origin.
Browser extensions interfering with request headers
Certain ad blockers, privacy tools, and developer extensions modify outgoing HTTP headers. If an extension injects a malformed or duplicate header, the server may reject the request.
Server-Side Causes
Misconfigured .htaccess rules (Apache)
Rewrite rules, redirect directives, or access control entries with syntax errors can cause Apache to generate a 400 before the request reaches the application layer.
Nginx configuration errors
Invalid server_name directives, broken location blocks, or incorrect proxy_pass settings can cause Nginx to return a 400 for requests it cannot route.
WAF or security plugin over-blocking
Web Application Firewalls — whether at the server level (ModSecurity), CDN level (Cloudflare WAF), or application level (WordPress security plugins) — can flag legitimate requests as malicious and return a 400 or 403. This is common when request parameters contain strings that match SQL injection or XSS signatures.
Application-level validation failures
Frameworks like Laravel, Django, or Express.js return 400 when input validation fails — for example, a required JSON field is absent, a date field is in the wrong format, or a numeric parameter receives a string value.
How to Fix a 400 Bad Request Error: Client-Side Steps
1. Validate and Correct the URL
Inspect the URL character by character. Pay particular attention to:
- Unencoded spaces: A space must be
%20, not a literal space or+(outside of form data). - Double slashes or missing slashes:
https://example.com//pathorhttps://example.com/path?with a dangling question mark. - Broken percent-encoding: A
%not followed by exactly two hexadecimal digits is illegal. - Non-ASCII characters: Domain names with Unicode characters must use Punycode; path segments with Unicode must be percent-encoded in UTF-8.
A correctly encoded URL looks like this:
https://example.com/search?q=hello%20world&lang=enNot like this:
https://example.com/search?q=hello world&lang=en2. Clear Browser Cookies and Cache
This resolves the majority of 400 errors encountered on sites the user has previously visited.
Google Chrome:
- Open
chrome://settings/clearBrowserData - Set the time range to All time
- Check Cookies and other site data and Cached images and files
- Click Clear data
Mozilla Firefox:
- Open
about:preferences#privacy - Under Cookies and Site Data, click Clear Data
- Select both options and confirm
Safari (macOS):
- Go to Safari > Settings > Privacy
- Click Manage Website Data, then Remove All
For a more targeted approach — especially useful when you do not want to lose all session data — use the browser's developer tools to delete only the cookies for the specific domain:
- Open DevTools (
F12orCmd+Option+I) - Navigate to Application > Storage > Cookies
- Select the domain and delete individual cookies
3. Flush the DNS Cache
Windows:
ipconfig /flushdnsmacOS (Ventura, Sonoma, Sequoia):
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponderLinux (systemd-resolved):
sudo systemd-resolve --flush-cachesLinux (nscd):
sudo service nscd restartAfter flushing, verify the resolution is correct before retrying:
nslookup example.com4. Disable Browser Extensions
Extensions that modify HTTP headers are the most likely culprits. Rather than disabling all extensions simultaneously, use the browser's incognito or private mode first — most extensions are disabled by default in private windows. If the page loads correctly in incognito, an extension is responsible.
To isolate the specific extension in Chrome:
- Navigate to
chrome://extensions/ - Disable all extensions
- Re-enable them one at a time, reloading the page after each
5. Test on a Different Browser, Device, or Network
This step quickly determines whether the issue is environment-specific. If the page loads on a mobile device using cellular data but fails on your desktop, the problem is likely local — either browser configuration, a network-level proxy, or a corporate firewall modifying request headers.
How to Fix a 400 Bad Request Error: Server-Side Steps
These steps apply to website owners, developers, and system administrators with access to the server or hosting control panel.
6. Analyze Server Access and Error Logs
Server logs are the definitive diagnostic tool. A 400 entry in the access log will show the raw request line that was rejected.
Nginx error log (default path):
tail -n 100 /var/log/nginx/error.log | grep " 400 "Apache error log:
tail -n 100 /var/log/apache2/error.logNginx access log — filter for 400 responses:
awk '$9 == 400' /var/log/nginx/access.log | tail -20Look for patterns: are 400s coming from a specific endpoint, a specific user agent, or a specific parameter? This narrows the root cause dramatically.
If you are running a VPS Hosting environment, you have direct SSH access to these logs. On managed Shared Web Hosting, access logs are typically available through cPanel's Errors section or via the Raw Access log download.
7. Audit the .htaccess File (Apache)
A single syntax error in .htaccess can cause Apache to return 400 or 500 errors for every request. Validate the file syntax without restarting Apache:
apachectl -tCommon .htaccess issues that produce 400 errors:
RewriteRulepatterns with unescaped special charactersLimitRequestBodyset to an unexpectedly low value- Malformed
Headerdirectives
Example of a problematic directive:
# This will cause a 400 if the header value is malformed
RequestHeader set X-Custom-Header "value with "quotes""Corrected version:
RequestHeader set X-Custom-Header "value with escaped quotes"8. Check Nginx Configuration
Validate the entire Nginx configuration before applying changes:
nginx -tPay attention to client_max_body_size if users are uploading files:
http {
client_max_body_size 50M;
}Also review large_client_header_buffers — if request headers (including cookies) exceed the buffer size, Nginx returns a 400:
http {
large_client_header_buffers 4 16k;
}After editing, reload without downtime:
nginx -s reload9. Increase File Upload Limits
If the 400 error occurs specifically during file uploads, the request body is likely exceeding the server's configured limit.
PHP (php.ini):
upload_max_filesize = 50M
post_max_size = 55MApache (httpd.conf or .htaccess):
LimitRequestBody 52428800Nginx (nginx.conf):
client_max_body_size 50M;Note that post_max_size in PHP must always be larger than upload_max_filesize, or PHP will silently discard the upload and the application may return a 400.
10. Review WAF Rules and Security Plugins
If you are running ModSecurity, Cloudflare WAF, or a WordPress security plugin (Wordfence, iThemes Security), temporarily disable the WAF rule set and test whether the 400 disappears. If it does, review the WAF audit log to identify which rule is triggering:
tail -f /var/log/modsec_audit.logDo not simply disable the WAF permanently. Instead, create a targeted exception for the legitimate request pattern that is being blocked.
400 Bad Request vs. Related HTTP Error Codes
Understanding where 400 sits in the HTTP error taxonomy prevents misdiagnosis.
| Status Code | Name | Fault Location | Typical Cause |
|---|---|---|---|
| — | — | — | — |
| 400 | Bad Request | Client | Malformed request syntax, invalid headers, bad encoding |
| 401 | Unauthorized | Client | Missing or invalid authentication credentials |
| 403 | Forbidden | Server policy | Valid request, but access is denied by server rules |
| 404 | Not Found | Server | Resource does not exist at the requested URI |
| 413 | Content Too Large | Client | Request body exceeds server's configured size limit |
| 414 | URI Too Long | Client | Request URI exceeds the server's maximum URI length |
| 422 | Unprocessable Content | Client | Syntactically valid but semantically incorrect (common in REST APIs) |
| 431 | Request Header Fields Too Large | Client | Individual or total header size exceeds server limits |
| 500 | Internal Server Error | Server | Unhandled exception or misconfiguration on the server |
| 502 | Bad Gateway | Server/Proxy | Upstream server returned an invalid response |
A key operational distinction: 413 (Content Too Large) is the more semantically precise code for oversized uploads, but many servers — particularly older Apache and Nginx configurations — return 400 instead. If you see a 400 on file upload, always check body size limits first.
400 Errors in API Contexts
REST and GraphQL APIs use 400 extensively as the standard response for input validation failures. If you are building or consuming an API, a 400 response body will typically contain a structured error payload:
{
"error": "Bad Request",
"message": "The 'email' field must be a valid email address.",
"field": "email",
"code": 400
}When debugging API 400 errors:
- Verify the
Content-Typeheader matches the body format (application/jsonfor JSON payloads,multipart/form-datafor file uploads) - Confirm required fields are present and correctly typed
- Check that string values do not exceed maximum length constraints
- Validate date and time formats against the API specification (ISO 8601 is standard:
2024-01-15T10:30:00Z) - Inspect the
Authorizationheader format — Bearer tokens must be prefixed withBearer, not passed raw
For teams running API services on Dedicated Servers, enabling detailed request logging at the application layer (not just the web server layer) is critical for diagnosing 400 patterns at scale.
Diagnosing 400 Errors with Browser Developer Tools
The browser's Network panel is the most precise client-side diagnostic tool available.
- Open DevTools (
F12) - Navigate to the Network tab
- Reproduce the request that triggers the 400
- Click on the failed request in the waterfall
- Inspect the Headers tab — review both Request Headers and Response Headers
- Check the Response tab for any error detail returned by the server
The Request Headers panel will show exactly what the browser sent. Compare this against what the server expects. Look specifically at:
Hostheader valueCookieheader size and contentContent-TypeandContent-Lengthfor POST/PUT requests- Any custom headers injected by extensions
Preventing 400 Errors in Web Applications
For developers and server administrators, proactive measures reduce the incidence of 400 errors significantly.
Input sanitization and validation at the application layer — Validate all user-supplied input before it reaches the server's routing layer. Return descriptive 400 responses with field-level error messages rather than generic failures.
Implement proper URL encoding in client code — Use built-in encoding functions rather than manual string manipulation:
// JavaScript — correct approach
const query = encodeURIComponent("hello world & more");
const url = `https://example.com/search?q=${query}`;# Python — correct approach
from urllib.parse import urlencode
params = urlencode({"q": "hello world & more"})
url = f"https://example.com/search?{params}"Set explicit and reasonable body size limits — Do not leave client_max_body_size at the default 1 MB if your application accepts file uploads. Equally, do not set it to unlimited — this creates a denial-of-service vector.
Monitor 400 rates in production — A sudden spike in 400 errors is often the first indicator of a bot scanning for vulnerabilities, a broken client-side form, or a deployment that introduced a breaking API change. Set up alerting on your 4xx error rate in your monitoring stack (Grafana, Datadog, CloudWatch).
Use HTTPS with a valid SSL certificate — Some 400 errors arise when clients send HTTPS requests to a server that is not properly configured for TLS, or when a certificate mismatch causes the TLS handshake to fail before the HTTP layer is even reached. Ensuring your SSL Certificates are valid, correctly installed, and cover all required subdomains eliminates this class of error entirely.
Configure control panel environments correctly — If you manage multiple sites through a control panel, misconfigured virtual host definitions are a common source of 400 errors. Environments using VPS with cPanel should verify that each domain's document root, SSL binding, and rewrite rules are correctly scoped to avoid cross-domain request contamination.
Decision Matrix: Diagnosing a 400 Error by Symptom
| Symptom | Most Likely Cause | First Action |
|---|---|---|
| — | — | — |
| 400 on every page of one site, works elsewhere | Corrupted site-specific cookie | Clear cookies for that domain only |
| 400 only when submitting a form or uploading | Payload too large or wrong `Content-Type` | Check server body size limits and form `enctype` |
| 400 on a URL you typed manually | URL encoding error or typo | Re-encode the URL; check for illegal characters |
| 400 in API calls only | Missing required header or invalid JSON | Inspect request headers and validate payload schema |
| 400 after a server config change | `.htaccess` or Nginx config syntax error | Run `apachectl -t` or `nginx -t` |
| 400 for all users simultaneously | WAF rule triggered or server misconfiguration | Check WAF audit log and server error log |
| 400 only in one browser | Extension injecting bad headers | Test in incognito; disable extensions |
| 400 after DNS change | DNS cache pointing to wrong server | Flush DNS cache; verify with `nslookup` |
Technical Checklist: Resolving a 400 Bad Request
For end users:
- Manually inspect and re-type the URL, correcting any encoding issues
- Clear cookies and cache specifically for the affected domain
- Test in a private/incognito window to rule out extensions
- Flush the local DNS cache
- Test on a different browser, device, and network connection
For developers and API consumers:
- Validate
Content-Typematches the request body format - Confirm all required fields and headers are present and correctly typed
- Check that string values, dates, and numeric types conform to the API contract
- Use
curlwith verbose output to inspect the raw HTTP exchange:
curl -v -X POST https://api.example.com/endpoint
-H "Content-Type: application/json"
-H "Authorization: Bearer YOUR_TOKEN"
-d '{"key": "value"}'For server administrators:
- Pull and grep server error logs for 400 entries
- Validate web server configuration syntax (
nginx -t/apachectl -t) - Check
client_max_body_size(Nginx) andLimitRequestBody(Apache) - Review
large_client_header_buffersin Nginx if cookie-heavy requests are failing - Audit WAF rules and check the ModSecurity audit log
- Verify SSL/TLS certificate validity and coverage
- Confirm
.htaccessrewrite rules are syntactically correct
—
FAQ
What is the difference between a 400 and a 404 error?
A 400 error means the server could not understand the request because it was malformed — the fault is in how the request was constructed. A 404 error means the request was valid and understood, but the requested resource simply does not exist on the server. They require entirely different fixes.
Can a 400 Bad Request error be caused by the server, not the client?
Yes, indirectly. A server misconfiguration — such as an overly restrictive WAF rule, an incorrect Nginx large_client_header_buffers setting, or a broken .htaccess directive — can cause the server to reject requests that are technically valid. In these cases, the HTTP specification is still being followed (the server is rejecting what it perceives as a bad request), but the real fault is in the server's configuration, not the client's request.
Why does clearing cookies fix a 400 error?
Cookies are sent in the Cookie request header on every request to the relevant domain. If a cookie stored in the browser is malformed, expired in a way the server does not accept, or has grown too large (exceeding large_client_header_buffers limits in Nginx), the server rejects the entire request with a 400 before processing it. Deleting the corrupted cookie removes the bad data from the header.
How do I fix a 400 error when uploading files to my website?
The upload is exceeding either the web server's body size limit or PHP's upload size limit. On Nginx, increase client_max_body_size in nginx.conf. On Apache, adjust LimitRequestBody in .htaccess or httpd.conf. For PHP applications, update upload_max_filesize and post_max_size in php.ini, ensuring post_max_size is larger than upload_max_filesize. Restart the relevant services after making changes.
How can I tell if a 400 error is coming from a CDN or WAF rather than my origin server?
Check the response headers. Cloudflare adds cf-ray and server: cloudflare headers. AWS CloudFront adds x-amz-cf-id. If these headers are present on the 400 response, the rejection happened at the edge, not at your origin. Review the CDN's WAF logs or firewall event dashboard to identify which rule triggered the block, then create a targeted exception for the legitimate traffic pattern.
