400 vs 403: Bad Request vs Forbidden
400 and 403 can look similar in logs, but they tell clients, crawlers, and API consumers different things.
| Aspect | HTTP 400 โ Bad Request | HTTP 403 โ Forbidden |
|---|---|---|
| Definition | The server received a request it cannot parse or understand. This is a client-side error โ the request itself is malformed. | Authentication is not the issue โ the authenticated user simply does not have permission to access the resource. Re-authenticating will not help. |
| Plain-language summary | The server cannot parse or process the request because it is malformed. The error is always on the client side โ the request itself is structurally invalid. Common causes include invalid JSON, missing required headers, malformed URL encoding, or a content type mismatch. | The client is authenticated but does not have permission to access the resource. The server understood the request and knows who the client is โ it simply refuses to authorize this specific action. Re-authenticating will not change the outcome. |
| When to use | Return 400 when the request is syntactically invalid or unparseable. Use 422 when the request is syntactically valid but semantically invalid (valid JSON that violates business rules). Use 401 for missing/invalid authentication, 403 for insufficient permissions, 404 for unknown resources. | Return 403 when the client is authenticated but lacks the required permissions, role, or scope. Use 401 when the issue is authentication (unauthenticated or invalid credentials). Use 404 when you do not want to reveal whether a resource exists at all (security-sensitive resources). |
| Client behavior | Do not retry automatically โ the same malformed request will receive the same 400. Fix the request format and retry. API clients should surface the error to the developer with the response body details. | Client should not retry without a change in permissions. Users should contact an administrator. Automated clients should surface the error and stop retrying. |
| Caching behavior | Not cached. Error responses are generally not stored. | Not cached. Permission checks are per-request. |
| SEO / crawler impact | Search crawlers interpret 400 (client-errors) for indexation and link equity accordingly. | Search crawlers interpret 403 (client-errors) for indexation and link equity accordingly. |
| API / backend impact | API clients branching on 400 expect Bad Request semantics. | API clients branching on 403 expect Forbidden semantics. |
| Safe to retry? | Only after fixing the underlying cause | Only after fixing the underlying cause |
Common real-world scenarios
When you see HTTP 400
In API logs, 400s indicate client-side integration bugs. Sudden spikes in 400s often correlate with: a bad client deployment sending malformed payloads, a frontend change that broke the request format, or an API schema change that old clients have not adopted. Monitor 400 rates per endpoint to detect client bugs early.
When you see HTTP 403
In logs, 403s indicate RBAC policy mismatches, tenant isolation violations (user A trying to access user B's data), or scope insufficient errors on OAuth tokens. Common production scenarios: a new user missing a required role, an API token created without a needed scope, or an IP allowlist blocking a new service IP.
Decision rule
Use 400 when the response should communicate bad request behavior; use 403 when forbidden is the accurate protocol signal.
A frequent mistake is swapping 400 and 403 for convenience; that causes client retry bugs, incorrect cache signals, and misleading monitoring data.
Use 400 when the correct protocol signal is Bad Request. Use 403 when the correct signal is Forbidden. Returning either code for the wrong reason breaks client expectations, cache behavior, and monitoring accuracy.
FAQ
What is the biggest difference between 400 and 403?
400 communicates Bad Request, while 403 communicates Forbidden. Choosing the right one keeps clients and intermediaries predictable.
Do 400 and 403 have SEO or caching impact?
Yes. Search engines and caches interpret status classes differently. Use each code according to its semantics to avoid accidental indexing, stale responses, or crawl inefficiency.
Can APIs safely return 400 instead of 403?
Only when it matches contract semantics. API clients often branch logic by exact code, so swapping them can break retries, auth handling, or user-facing errors.
Full guides
HTTP 400 Bad Request โ full guide ยท HTTP 403 Forbidden โ full guide ยท HTTP 403 status reference ยท All comparisons ยท HTTP 400 status reference