Both HTTP 400 and HTTP 404 are 4xx Client Error status codes, but they pinpoint fundamentally different stages of request processing.
Core differences
- HTTP 400 Bad Request: The server cannot or will not process the request because something is wrong with how the message was constructed (e.g., broken JSON syntax, invalid percent-encoding, or oversized headers).
- HTTP 404 Not Found: The server understood the request structure perfectly, but the resource identified by the Request-URI does not exist or cannot be found.
Practical scenario: Query parameters vs IDs
Consider an API endpoint: /v1/users/{id}?fields={list}
- If a client requests
/v1/users/nonexistent-id-999: The URL syntax is valid, but the user record does not exist in the database $\to$ HTTP 404 Not Found. - If a client requests
/v1/users/123?fields=name%2: The percent-encoding is broken and cannot be decoded by the web server $\to$ HTTP 400 Bad Request.
How to test with curl
curl -i https://api.example.test/v1/users/missing-id
Key takeaway
Use 400 Bad Request when the request itself contains syntax, framing, or encoding defects. Use 404 Not Found when the request is syntactically valid but targets a non-existent route or resource.