Pick the Right 4xx Code for Your API Response

Decide which 4xx code fits your API scenario: 400 vs 422 for validation, 401 vs 403 for access, 404 vs 410 for deleted resources, and where 409 and 429 fit in.

ZERO UPLOAD · ALL LOCAL
  1. Type a code number (e.g. 404) to find codes by number only, or a word (e.g. "timeout", "rate limit") to search names and detail content.
  2. Use the category pills (1xx–5xx) to browse codes by class when not searching.
  3. Click Details on any card to expand causes and resolution steps in a full-width panel below the row.
  4. Click Copy Markdown on an expanded card to copy a ready-to-paste summary for Jira tickets, GitHub issues, or Slack.

4xx codes covered in this guide

  • 401 Unauthorized credentials missing or invalid — client should authenticate and retry
  • 403 Forbidden credentials valid but the identity lacks permission
  • 404 vs 410 404 for absent resources, 410 for deliberately and permanently removed ones
  • 409 Conflict request conflicts with current resource state — duplicate key, optimistic lock failure
  • 429 Too Many Requests defined in RFC 6585, pairs with a Retry-After header

1XX INFORMATIONAL — 4 codes

100 Continue
RFC 9110
101 Switching Protocols
RFC 9110
102 Processing
RFC 2518
103 Early Hints
RFC 8297

2XX SUCCESS — 10 codes

200 OK
RFC 9110
201 Created
RFC 9110
202 Accepted
RFC 9110
203 Non-Authoritative Information
RFC 9110
204 No Content
RFC 9110
205 Reset Content
RFC 9110
206 Partial Content
RFC 9110
207 Multi-Status
RFC 4918
208 Already Reported
RFC 5842
226 IM Used
RFC 3229

3XX REDIRECTION — 8 codes

300 Multiple Choices
RFC 9110
301 Moved Permanently
RFC 9110
302 Found
RFC 9110
303 See Other
RFC 9110
304 Not Modified
RFC 9110
305 Use Proxy
RFC 9110
307 Temporary Redirect
RFC 9110
308 Permanent Redirect
RFC 9110

4XX CLIENT ERROR — 35 codes

400 Bad Request
RFC 9110
401 Unauthorized
RFC 9110
402 Payment Required
RFC 9110
403 Forbidden
RFC 9110
404 Not Found
RFC 9110
405 Method Not Allowed
RFC 9110
406 Not Acceptable
RFC 9110
407 Proxy Authentication Required
RFC 9110
408 Request Timeout
RFC 9110
409 Conflict
RFC 9110
410 Gone
RFC 9110
411 Length Required
RFC 9110
412 Precondition Failed
RFC 9110
413 Content Too Large
RFC 9110
414 URI Too Long
RFC 9110
415 Unsupported Media Type
RFC 9110
416 Range Not Satisfiable
RFC 9110
417 Expectation Failed
RFC 9110
418 I'm a Teapot (Unofficial)
RFC 2324
420 Enhance Your Calm (Unofficial)
Twitter
421 Misdirected Request
RFC 9110
422 Unprocessable Content
RFC 9110
423 Locked
RFC 4918
424 Failed Dependency
RFC 4918
425 Too Early
RFC 8470
426 Upgrade Required
RFC 9110
428 Precondition Required
RFC 6585
429 Too Many Requests
RFC 6585
431 Request Header Fields Too Large
RFC 6585
444 No Response (Unofficial)
nginx
451 Unavailable For Legal Reasons
RFC 7725
494 Request Header Too Large (Unofficial)
nginx
495 SSL Certificate Error (Unofficial)
nginx
496 SSL Certificate Required (Unofficial)
nginx
499 Client Closed Request (Unofficial)
nginx

5XX SERVER ERROR — 19 codes

500 Internal Server Error
RFC 9110
501 Not Implemented
RFC 9110
502 Bad Gateway
RFC 9110
503 Service Unavailable
RFC 9110
504 Gateway Timeout
RFC 9110
505 HTTP Version Not Supported
RFC 9110
506 Variant Also Negotiates
RFC 2295
507 Insufficient Storage
RFC 4918
508 Loop Detected
RFC 5842
510 Not Extended
RFC 2774
511 Network Authentication Required
RFC 6585
520 Web Server Returns an Unknown Error (Unofficial)
Cloudflare
521 Web Server Is Down (Unofficial)
Cloudflare
522 Connection Timed Out (Unofficial)
Cloudflare
523 Origin Is Unreachable (Unofficial)
Cloudflare
524 A Timeout Occurred (Unofficial)
Cloudflare
525 SSL Handshake Failed (Unofficial)
Cloudflare
526 Invalid SSL Certificate (Unofficial)
Cloudflare
527 Railgun Listener to Origin Error (Unofficial)
Cloudflare
No codes match your search.

Pick the Right 4xx Client Error Code for Your API

Picking the right 4xx code for your API response means matching the client-side problem to its precise semantic category: bad syntax, missing credentials, insufficient permissions, or resource absence. The 4xx class covers every situation where the server understood the request but could not or would not fulfill it, and unlike 5xx errors, the fault sits with the client, so retrying the same request without changing it will not help. Yet knowing which 4xx code applies to a given situation requires understanding the semantic distinctions between codes that look superficially similar: 401 vs 403, 400 vs 422, 404 vs 410. What follows walks through the decision rules for each code used most often in REST API design, so you can pick the right one the next time your team debates it.1

Authentication and authorisation codes

Two pairs of codes handle auth failures, and choosing the correct one prevents your clients from wasting time re-authenticating when the real problem is a permissions issue rather than a missing credential. Return 401 Unauthorized when the request lacks credentials or when the credentials provided are invalid: the client should authenticate and retry. Return 403 Forbidden when credentials are present and valid but the authenticated identity lacks permission for this specific operation.

Some APIs return 404 instead of 403 for protected resources to avoid disclosing that the resource exists to an unauthenticated or underprivileged caller. This is a valid security pattern for private data such as user profiles or internal documents, but it creates a more confusing developer experience because the client cannot distinguish between a missing endpoint and a deliberate concealment of access restrictions. 407 Proxy Authentication Required is similar to 401 but applies to proxy authentication, not server authentication: the client must authenticate with the proxy before the request reaches your origin, which matters in corporate environments where all traffic flows through an authenticating forward proxy.

Applying the correct code prevents clients from entering authentication retry loops when the real problem is a permissions configuration error that no amount of re-authentication will resolve. The distinction matters most in multi-tenant applications where different user roles have overlapping but distinct permission boundaries: returning 401 in response to a role-based access denial forces the client to re-authenticate with fresh credentials, when the actual fix requires an administrator to adjust the role assignment rather than the client to present new credentials.2

Resource errors: 404, 405, 409, 410

Four codes cover conditions where the resource state or request method is the problem, and selecting the right one ensures your clients receive actionable information about why their request was rejected. Choosing the wrong code forces clients to guess whether they should change the URI, switch the HTTP method, or resolve a state conflict before retrying, so the distinctions carry real consequences for API usability.

404, 405, and 409

404 Not Found applies when the requested URI maps to no resource in your system, whether because the resource never existed, was deleted, or the client constructed an invalid path from outdated documentation. 405 Method Not Allowed applies when the URI is valid but the HTTP method is not permitted: a POST to a read-only endpoint. The server must include an Allow header listing the permitted methods on a 405 response so the client knows which methods it can retry with. 409 Conflict applies when the request cannot be completed because of a conflict with the current state of the resource: a PUT that attempts to update a resource that has been modified since the client last read it, or a POST that tries to create a resource with a duplicate key.

410 Gone is a permanent version of 404: the resource existed and was deliberately removed by an administrator or through a documented deletion workflow. Search engines deindex a 410 URL faster than a 404, which is why choosing 410 over 404 for removed content accelerates how quickly search results reflect the deletion.

Rate limiting: 429

429 Too Many Requests is the designated code for rate limiting, defined in RFC 6585 rather than RFC 9110.3 When a client exceeds a request quota, the server returns 429 with an optional Retry-After header indicating how long to wait. The Retry-After header makes 429 a cooperative signal: the client knows exactly when to retry rather than guessing a backoff duration.

Well-behaved clients implement Retry-After inspection as their first response to a 429. Many client libraries and HTTP frameworks do not inspect Retry-After automatically, so developers must implement this behaviour explicitly. Failing to honour Retry-After causes clients to retry too early, which wastes bandwidth and can extend the duration of a rate-limit event by triggering escalating penalties from the server.

A common mistake is returning 503 for rate-limit exhaustion: 503 implies the service is globally unavailable, which is incorrect when only a specific client is being throttled. 429 is semantically precise about the scope of the limit. Returning 503 instead of 429 also misleads monitoring systems into treating a per-client throttle as a global outage, which can trigger unnecessary paging for on-call engineers and distort service health dashboards during routine traffic spikes.

409 Conflict versus 422 for duplicate key errors

Duplicate unique key errors are a common source of 4xx code confusion in REST API design. When a POST creates a resource with a field value that must be unique, and the value already exists, the request conflicts with the current state of the resource. This is a 409 Conflict: the request is structurally valid and semantically valid in isolation, but the current resource state prevents it from completing. Returning 422 for a duplicate key error misclassifies the problem as a semantic validation failure rather than a state conflict.

The distinction matters for client behavior. A 422 tells the client the submitted data is inherently invalid: the client should fix the input and resubmit. A 409 tells the client the submitted data is valid but conflicts with existing state: the client might resolve the conflict by updating the existing resource or by informing the user that the resource already exists. These are different client behaviors, and the status code is supposed to drive the right one.

409 for optimistic locking failures

Optimistic locking failures are another canonical 409 case. When a client reads a resource, modifies it locally, and sends a PUT with an If-Match header containing the ETag it read, the server compares the current ETag with the If-Match value. If another client modified the resource between the read and the write, the ETags do not match. Some APIs prefer 409 here because it carries the semantic meaning of "your update conflicts with a concurrent modification," which is more descriptive than the generic 412 Precondition Failed code.

Conditional requests and 412 Precondition Failed

412 Precondition Failed is the response to a conditional request where the condition evaluates to false. Conditional requests include an If-Match, If-None-Match, If-Modified-Since, or If-Unmodified-Since header that the server evaluates before processing the request. A PUT with If-Match: "etag-value" tells the server to apply the update only if the resource's current ETag matches. If another client modified the resource first, the ETags do not match and the server returns 412 rather than applying the update.

412 is the foundation of optimistic locking in HTTP APIs. It allows multiple clients to read and modify resources concurrently without explicit locks, using the ETag as a version identifier. The client reads the resource, receives an ETag, modifies the resource locally, and sends the modification with If-Match. If the server returns 412, the client knows another modification happened and must re-read the resource before retrying.

Including the current ETag in a 412 response

A 412 response should include the current ETag in the response headers so the client can immediately compare it to the one it sent. Without the current ETag in the response, the client must make a separate GET request to retrieve it before retrying the conditional update. Setting ETag on the 412 response saves a round trip and gives the client the information it needs to decide whether to re-read and merge or to surface a conflict message to the user.

When to use this

Decide which 4xx code fits here whenever your team debates 400 vs 422 for a validation failure, 401 vs 403 for an access denial, or 404 vs 410 for a deleted resource. Check the rate-limiting section too before you default to 503 for a throttled client.

Examples

POST /api/users — JSON body is missing the required email field

Return 400 Bad Request. A missing required field is a structural problem that a JSON schema validator would catch. Reserve 422 for semantically invalid content that parses correctly.

GET /api/orders/999 — authenticated user attempts to view another user's order

Return 403 Forbidden (or 404 if you want to conceal the resource exists). The credentials are valid but the identity lacks permission. Do not return 401: re-authenticating will not help.

POST /api/products — product SKU already exists in the database

Return 409 Conflict. The request is well-formed and authenticated but conflicts with existing resource state. Include the conflicting field and value in the response body.

Sources
  1. 1.

    R. Fielding, Ed., M. Nottingham, Ed., and J. Reschke, Ed., "HTTP Semantics," RFC 9110, IETF, June 2022. https://www.rfc-editor.org/rfc/rfc9110.txt

  2. 2.

    Mozilla Developer Network, "HTTP response status codes," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

  3. 3.

    M. Nottingham and R. Tarreau, "Additional HTTP Status Codes," RFC 6585, IETF, April 2012. https://www.rfc-editor.org/rfc/rfc6585.txt

FAQ