Every HTTP response starts with a three-digit status code. The first digit tells you the category; the specific code tells you what happened. Knowing the common ones speeds up debugging websites, APIs and server configs.

Range Category
1xx Informational
2xx Success
3xx Redirection
4xx Client error (the request was wrong)
5xx Server error (the server failed)

Check a URL’s status:

curl -s -o /dev/null -w '%{http_code}\n' https://example.com/page
curl -sI https://example.com/page | head -1

1xx

  • 101 Switching Protocols — WebSocket upgrades. See WebSockets through Nginx.
  • 103 Early Hints — preload hints sent before the final response.

2xx: success

  • 200 OK — the normal response.
  • 201 Created — a resource was created (APIs, after POST).
  • 204 No Content — success with no body (DELETE, CORS preflight).
  • 206 Partial Content — range requests (video seeking, resumed downloads).

3xx: redirects

  • 301 Moved Permanently — the URL changed for good; search engines transfer ranking. Use for domain moves, HTTPS, URL restructuring.
  • 302 Found — temporary redirect.
  • 304 Not Modified — the cached copy is still valid (ETag/Last-Modified revalidation). Good — saves bandwidth.
  • 307 Temporary Redirect / 308 Permanent Redirect — like 302/301 but the method and body are preserved (POST stays POST).

See 301 vs 302 redirects and Nginx redirects. Watch for redirect chains and loops (ERR_TOO_MANY_REDIRECTS) — see WordPress too many redirects.

4xx: client errors

  • 400 Bad Request — malformed request, invalid JSON, oversized headers/cookies, or (Django) a host not in ALLOWED_HOSTS.
  • 401 Unauthorized — authentication required or failed (basic auth, missing API token).
  • 403 Forbidden — authenticated or not, access is refused: file permissions, deny rules, WAF blocks. See Nginx 403.
  • 404 Not Found — no resource at that URL: wrong path, missing file, broken permalinks. See WordPress permalinks 404.
  • 405 Method Not Allowed — e.g. POST to a static file.
  • 408 Request Timeout — the client was too slow sending the request.
  • 410 Gone — removed permanently; search engines drop it faster than a 404. Useful when deleting content on purpose.
  • 413 Content Too Large — upload exceeds limits. See Nginx 413.
  • 414 URI Too Long — enormous query strings.
  • 419 (Laravel) — expired CSRF token/session.
  • 429 Too Many Requests — rate limited. See Nginx rate limiting.
  • 444 (Nginx-specific) — connection closed without a response; used to drop bad requests.
  • 499 (Nginx log only) — the client closed the connection before the server responded (impatient user or a proxy timeout upstream).

5xx: server errors

  • 500 Internal Server Error — the application crashed or a config error occurred. Check application and PHP error logs.
  • 502 Bad Gateway — the proxy got an invalid response from the backend: app down, wrong socket/port. See Nginx 502.
  • 503 Service Unavailable — overloaded or in maintenance; should include Retry-After. Return 503 (not 200 or 404) during planned maintenance so search engines come back later.
  • 504 Gateway Timeout — the backend was too slow. See Nginx 504.
  • 507/508 — storage or resource limits (some shared hosts use 508 “Resource Limit Reached”).

CDNs add their own codes — Cloudflare’s 520–526 indicate problems between Cloudflare and your origin (e.g. 521: origin refused the connection, 522: timeout, 525/526: SSL problems at the origin).

Status codes and SEO

  • Use 301 for permanent moves; avoid long chains.
  • Return a real 404/410 for missing pages, not a 200 “not found” page (“soft 404”).
  • Use 503 for temporary outages.
  • Keep 5xx errors rare — repeated server errors make crawlers slow down.

Find problems in your logs

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
awk '$9 ~ /^5/ {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

See Nginx access and error logs.

  • HTTP
  • Web Development
  • Troubleshooting