HTTP status codes

The codes that actually matter in production — and the ones applications routinely get wrong.

The five classes

RangeMeaning
1xxInformational — keep going
2xxSuccess
3xxRedirection — go elsewhere
4xxClient error — fix the request
5xxServer error — we broke something

The ones you will meet daily

CodeUse it for
200 OKStandard success with a body
201 CreatedResource created — send Location
204 No ContentSuccess, nothing to return
301 / 308Permanent redirect (308 preserves the method)
302 / 307Temporary redirect (307 preserves the method)
304 Not ModifiedCache is still valid — for conditional requests
400 Bad RequestMalformed request; failed validation
401 UnauthorizedAuthentication required or invalid
403 ForbiddenAuthenticated but not permitted
404 Not FoundNo such resource
409 ConflictState conflict (duplicate, wrong version)
422Well-formed but semantically invalid
429 Too Many RequestsRate limited — include Retry-After
500Unhandled server fault
502 / 503 / 504Bad gateway / unavailable / gateway timeout

Common mistakes

  • Returning 200 with an error body: clients cannot tell success from failure without parsing.
  • Using 401 where 403 belongs: 401 means 'who are you?', 403 means 'I know who you are, and no'.
  • Returning 404 for resources the user may not know exist — sometimes 403/404 by choice for privacy.
  • Redirecting POST with 302 — many clients convert it to GET. Use 307/308 to preserve the method.
⚠️
Do not return 3xx from an API endpoint expecting JSON unless redirect following is guaranteed. Many clients will not follow, and the redirect body gets ignored.

FAQ

Should validation failures be 400 or 422?
Either is defensible; 400 is the broad 'bad request' and 422 signals syntactically valid but semantically rejected. Pick one and document it.
What should I return for a health check?
200 with a tiny body, or 503 when dependencies are unhealthy so load balancers can pull the instance out.

HTTP methods HTTP headers

Last refreshed 2026-09-17.