← All Status Codes
400
Bad Request
⚠️ Client Error Low Risk

📖 What Is HTTP 400?

The server cannot process the request due to malformed syntax, invalid request framing, or deceptive request routing.

🛡️ Security Implications

Often triggered by security scanners and attack attempts. A high volume of 400 errors may indicate active scanning or fuzzing.

🔍 Common Causes

Malformed JSON/XML body, missing required parameters, invalid URL encoding, oversized headers, or corrupted request.

🔧 How to Fix

Check request format and encoding. Validate Content-Type matches the body format. Check for special characters in URLs.

🖥️ How to Check

curl -I -o /dev/null -w "%{http_code}" https://example.com

HTTP 400 in depth — what you actually need to know

HTTP 400 Bad Request indicates the server cannot or will not process the request because it appears malformed — invalid syntax, missing required fields, malformed JSON, oversized headers, invalid URL encoding. The request itself is the problem; retrying without changes will produce the same 400.

400 is the generic "client did something wrong" code. More specific codes (401 unauthorised, 403 forbidden, 404 not found, 422 validation error) are preferred when applicable. Returning 400 for everything client-error is a code smell — proper categorisation helps debugging and helps surrounding systems (monitoring, log analysis) interpret error patterns.

From a security perspective, 400 responses sometimes leak information about server-side parsing logic. Detailed error messages ("expected JSON field user_id of type integer at position 47") help debugging but tell attackers about your data structures and validation logic. Production responses should typically use generic error messages; detailed errors stay in logs accessible to operators only.

Five real-world scenarios involving HTTP 400

API request validation

APIs validate incoming requests for required fields, correct types, value ranges, and business logic constraints. Failed validation returns 400 (or 422 for semantic validation specifically). Standard API pattern; well-designed APIs have consistent validation behaviour and helpful (but not over-detailed) error responses.

Web application form validation

Forms validate inputs server-side (after client-side validation, which is convenience not security). Validation failures return 400 with field-level error indication. Modern frameworks render validation errors in the UI from the 400 response.

API fuzzing during pentests

Pentest tools fuzz API endpoints with malformed inputs to discover error-handling vulnerabilities. 400 responses are normal; the interesting cases are when fuzzing produces 500 responses (indicating server-side crash on bad input — possible exploitable bug).

Bug bounty — over-detailed error messages

Hunters look for 400 responses that leak information: stack traces in error messages, internal file paths, database error details, framework versions. Each leak is potentially a valid bug bounty finding for security-conscious programs.

WAF / API gateway behaviour

WAFs and API gateways frequently return 400 for requests that violate their rules (oversized headers, suspicious patterns, malformed payloads). The 400 originates from the gateway, not the application. Distinguish in logs whether 400s come from app validation or gateway rejection.

Common mistakes & edge cases

Returning 400 with full stack traces in production

Stack traces leak internal application structure, framework versions, file paths, and sometimes data values. Configure environment-aware error responses: detailed in dev, generic in prod with correlation IDs to logs.

Returning 400 when 401 or 403 is more semantically correct

400 is generic client error. If the issue is authentication, use 401. If the issue is authorisation, use 403. If the issue is business validation specifically, 422 is more specific. Use the right code for the actual condition.

Echoing user input in 400 error messages without sanitisation

Error message like "Invalid value for field X: " with unsanitised user input in the message creates XSS in error responses. Always sanitise user input when echoed in any response, including error responses.

Generic "Bad Request" without correlation ID for log lookup

Generic errors in production protect from information leakage but make debugging hard if you cannot correlate user reports to log entries. Include a correlation ID in the response: "Error ID: abc123" — operators can look up the detailed error in logs by ID.

Not validating Content-Type headers

APIs that accept JSON should require Content-Type: application/json. Requests with wrong Content-Type or none at all should get 400 (or 415 Unsupported Media Type) rather than crashing the parser. Catch this at framework level.

Returning 400 for CORS preflight failures

CORS preflight (OPTIONS request) failures should follow CORS protocol — not 400 generally. Properly configured CORS handling is independent of generic request validation.

Frequently Asked Questions about HTTP 400

The server cannot or will not process the request because it appears malformed — invalid syntax, missing required fields, malformed JSON, oversized headers, etc. The request needs to be fixed before retry. Generic client-error code; more specific codes (401, 403, 404, 422) preferred when applicable.
400 = generic "request is malformed". 401 = unauthenticated (no credentials or invalid credentials). 403 = authenticated but not authorised for this resource. 404 = resource not found. 422 = request is well-formed but contains semantic validation errors. Use the specific code matching the actual condition.
Production: generic message ("Bad Request") plus a correlation ID for log lookup. Development: detailed errors helpful for debugging. Field-level validation errors are useful (e.g., "field email_address is required") but should not include stack traces or internal implementation details.
They leak information about server-side structure: framework versions (helps attackers select known exploits), database schema (helps SQL injection), file paths (helps directory traversal), validation logic (helps bypass-attempt crafting). Each piece of information makes attacker reconnaissance easier.
Most frameworks support this. Django: DEBUG = False in production. Rails: production environment by default. Express: error-handler middleware with environment check. Implement structured logging with correlation IDs so operators can look up production errors by ID.
400 = request syntactically malformed (broken JSON, missing required headers, invalid URL encoding). 422 = request is syntactically valid but contains semantic validation errors (email field is well-formed but already-registered). Use 422 specifically when validation logic rejects the well-formed request.
Search engines crawling your site rarely cause 400 errors (they use GET requests with simple URLs). 400 in your logs typically comes from real users with malformed requests, automated scanners, or API clients with bugs. SEO impact is minimal.
WAFs return 400 (or 403, depending on config) when requests violate their rules — SQL injection patterns, XSS payloads, oversized requests, suspicious user agents. API gateways return 400 for requests violating API contract — wrong Content-Type, missing required headers, payloads too large.
Yes — clients producing many 400s are often attacking (fuzzing, brute force) or buggy. Rate limit by source IP after a threshold of 400s in a time window. Returns 429 Too Many Requests after threshold; reduces attack effectiveness and protects backend resources.
Most monitoring tools (Datadog, Grafana, New Relic) show 4xx and 5xx rates by default. Alert on sudden spikes. Distinguish 400s from app validation (might indicate frontend bugs) vs gateway rejection (might indicate WAF rule changes or attack patterns).