HomeProjectsBlogContact

HTTP Status Codes Explained: The Ones You'll Actually Use

There are dozens of HTTP status codes, but about fifteen cover nearly everything. What each one means, when to return it, and the mix-ups (401 vs 403, 301 vs 302) that confuse everyone.

HTTP Status Codes Explained: The Ones You'll Actually Use

Every HTTP response starts with a three-digit number that tells the client what happened. Get these right and browsers, search engines, caches, monitoring tools and frontend code all behave sensibly. Get them wrong, like returning 200 OK with an error message inside, and you create bugs that are surprisingly hard to track down.

The five families

The first digit tells you the category:

Range Meaning
1xx Informational. Rarely something you handle directly.
2xx Success.
3xx Redirection. Look somewhere else.
4xx Client error. The request was wrong.
5xx Server error. The server failed.

Even a client that doesn't recognise a specific code knows how to treat it from its family.

Success codes

  • 200 OK: the standard success response for reads and most updates.
  • 201 Created: a new resource was created. Return it, or its URL in a Location header.
  • 204 No Content: success with nothing to send back, typical for deletes.

Redirects (and the SEO mix-up)

  • 301 Moved Permanently: the resource has a new permanent URL. Search engines transfer ranking signals to the new URL. Use it for domain moves and changed slugs.
  • 302 Found: a temporary redirect. The original URL stays the canonical one.
  • 307 / 308: like 302 and 301 respectively, but they guarantee the request method and body stay the same. Useful for APIs, where a POST shouldn't silently become a GET.
  • 304 Not Modified: "your cached copy is still good." Sent in reply to conditional requests using ETag or Last-Modified. It saves bandwidth. (Caching strategies.)

A classic mistake is using 302 for permanent moves. The page might still rank, but you're sending mixed signals. If it's permanent, use 301 (or 308).

Client errors

  • 400 Bad Request: malformed request or failed validation.
  • 401 Unauthorized: despite the name, this means unauthenticated. "I don't know who you are." Log in and try again.
  • 403 Forbidden: "I know who you are, and you're not allowed." Logging in again won't help.
  • 404 Not Found: nothing here. Also commonly used instead of 403 to avoid revealing that a private resource exists.
  • 405 Method Not Allowed: the URL exists, but not for that method (say, DELETE on a read-only resource).
  • 409 Conflict: the request conflicts with current state, like registering an email that's already taken.
  • 410 Gone: removed on purpose and not coming back. Search engines drop these faster than 404s.
  • 413 Content Too Large: the request body, often an upload, exceeds the limit.
  • 422 Unprocessable Content: syntactically fine, but it fails business rules. Some APIs use 400 for this instead; just be consistent.
  • 429 Too Many Requests: rate limited. Include a Retry-After header. (Rate limiting guide.)

Server errors

  • 500 Internal Server Error: something broke in your code. The details belong in your logs, never in the response.
  • 502 Bad Gateway: a proxy or load balancer got an invalid response from the app behind it. Often the app crashed or isn't running.
  • 503 Service Unavailable: temporarily down, during maintenance or overload. Add Retry-After if you know when it'll be back.
  • 504 Gateway Timeout: the proxy gave up waiting for the app. Look for slow queries or a hung external call.

When you see 502 or 504 from Nginx or a hosting platform, the problem is almost always the application behind it, not the proxy itself. (Reading errors effectively.)

Mistakes worth avoiding

  • 200 with {"error": "..."}. Monitoring sees success, caches may store the error, and clients have to parse every body to find out what happened.
  • "Soft 404s": a "page not found" message returned with status 200. Search engines may index your error page. Return a real 404.
  • 500 for user mistakes. If the client sent bad input, that's a 4xx. Reserve 5xx for genuine server failures so your alerts stay meaningful.
  • Leaking details. Stack traces and SQL errors in a 500 response help attackers more than users.

A quick decision guide

  1. Did it work? 2xx. Created something? 201.
  2. Is it somewhere else? 301 (permanent) or 302 (temporary).
  3. Is the client unauthenticated? 401. Authenticated but not allowed? 403.
  4. Does it not exist? 404.
  5. Is the input invalid? 400 or 422.
  6. Too many requests? 429.
  7. Did your code fail? 500. Did something upstream fail? 502, 503 or 504.

For designing APIs around these codes, see REST API design best practices.

FAQ

What is the difference between 401 and 403?

401 means the request isn't authenticated, so the client should log in. 403 means the client is authenticated but doesn't have permission, so logging in again won't help.

Should I use 301 or 302 for SEO?

Use 301 (or 308) for permanent moves so search engines transfer signals to the new URL. Use 302 (or 307) only for genuinely temporary redirects.

What causes a 502 Bad Gateway error?

A proxy or load balancer received an invalid response from the server behind it, typically because the application crashed, isn't running, or is listening on a different port.

Keep reading

More from the workbench

All articles →