Complete reference for 50 HTTP status codes — what they mean, security implications, common causes, and how to fix them. Critical for incident response, web security, and API development.
HTTP status codes are 3-digit responses servers return to indicate the result of every HTTP request. The first digit groups them into 5 categories: 1xx informational (request received, continuing), 2xx success (request succeeded — 200 OK is the canonical success response), 3xx redirection (further action needed — most commonly 301 permanent and 302 temporary), 4xx client error (the request had a problem — 404 not found, 401 unauthorized, 403 forbidden), 5xx server error (the server had a problem — 500 internal server error, 502 bad gateway, 503 service unavailable).
Why they matter for security. Status codes are part of your server\'s observable behaviour. Every HTTP response leaks the status code, and the codes returned for specific requests reveal information about the server\'s state. Returning 401 on /admin/.htpasswd tells the attacker that file exists and is auth-protected. Returning 404 on the same path tells them the file probably does not exist. Returning 403 tells them backup directories are common enough to be specifically blocked. The pattern of status codes you return is part of your attack surface.
The reference grid above covers all 50 standard HTTP status codes, organised by category, with severity classification reflecting how often each code appears in attack scenarios. Each code links through to /http-status/N/ for the full per-code detail page with security implications, common causes, and fix guidance. Use the search field to jump directly to any code by number or name.
What "severity" means here. Critical: codes that strongly indicate security misconfiguration when seen unexpectedly (500 with full stack trace, 401 on resources that should be 404). High: codes that affect security posture (403 patterns revealing path structure, 502 leaking infrastructure). Medium: codes with notable but contextual security relevance (301/302 redirects, 429 rate limiting). Low/Info: standard informational responses. Severity is contextual — a 200 returned on a sensitive endpoint without authentication is a critical bug, not low-severity success.
Your log dashboard shows a spike in 401s, 403s, or 500s. Look up the codes in the encyclopedia for the security context — a 401 spike usually means brute-force authentication attempts; a 403 spike often means scanner traffic probing for restricted paths; a 500 spike usually means application bugs (or attempted exploitation triggering errors). The right diagnostic next step depends on which code is spiking.
Penetration test — interpreting target responses
During recon, you map the target by sending varied requests and observing status codes. The encyclopedia tells you what each code likely means in the target\'s configuration — 401 with WWW-Authenticate suggests basic auth, 403 with custom error page suggests app-layer auth, 404 vs 410 distinguishes "missing" from "intentionally removed". Speed up the recon-to-action transition by knowing what each response signal means.
API development — choosing the right status code to return
When designing API responses, choosing the right status code matters more than for web pages because client code reacts to the code. The encyclopedia documents convention for each code — 401 for "no/invalid token", 403 for "valid token but insufficient scope", 422 for "valid format but failed validation", 429 for rate limiting. Wrong codes cause client retry storms, false alerts, or silent failures.
Security training — explaining HTTP basics to non-security teams
For developer or QA onboarding, the encyclopedia provides ready examples for each common code. Showing "this is what 401 means, this is when you return it, this is what attackers infer if you return it incorrectly" makes status-code security concrete instead of abstract. The per-code detail pages give you teaching content without rebuilding it from scratch.
Web server hardening — designing custom error pages
Production servers should return generic 500 pages without stack traces. The encyclopedia documents what each common error code should NOT leak in production — file paths, framework versions, database errors, internal IPs. Use the per-code detail pages to build a checklist of what to redact in your custom error templates before going live.
Common mistakes & edge cases
Returning detailed 500 errors in production
Default framework behaviour shows full stack traces, file paths, query syntax, environment variables in 500 pages — useful in development, catastrophic in production. Always set the production environment flag explicitly so frameworks return generic 500 pages. Detailed errors go to logs only, not to the response body.
Distinguishing 401 vs 404 on sensitive paths
Returning 401 for /admin/secret.txt tells attackers it exists. Returning 404 for the same path hides whether it exists. For paths you do not want enumerated, return 404 even when the file exists but the user is unauthorised — fail closed and silent.
Confusing 301 and 302 redirects
301 (permanent) is cached aggressively by browsers and search engines; 302 (temporary) is re-checked each time. Use 301 for HTTP→HTTPS upgrades (you want HSTS-locked); use 302 for short-term maintenance redirects. Wrong choice persists for months because browsers cached it.
Returning 200 for invalid input
Some applications return 200 OK with an error message in the body for invalid input instead of the appropriate 4xx code. This breaks API clients (which check status codes, not body content) and can hide authentication bypass bugs (the 200 looks like success in monitoring while the actual operation failed silently).
Ignoring 429 rate limit responses
Returning 429 without a Retry-After header tells the client "you are being rate limited" but not "for how long". Properly-implemented 429 includes Retry-After, allowing legitimate clients to back off appropriately. Without it, clients either give up or retry blindly — both wrong.
Custom status codes outside the standard set
Some frameworks or proxies return non-standard codes (599, 419, 420). These are not standardised and cause unpredictable client behaviour — some clients treat them as 5xx errors, others as success, others crash. Stick to standard codes; if you need custom signalling, use response body content with a standard 200 or 4xx wrapper.
Frequently Asked Questions
HTTP status codes are 3-digit responses servers return to indicate the result of a request. The first digit groups them: 1xx informational, 2xx success, 3xx redirect, 4xx client error, 5xx server error. They matter for security because the codes a server returns leak information about its state and configuration. A 401 vs 403 vs 404 on the same URL tells attackers different things; verbose 500 errors can disclose stack traces and internal paths; 200 returned for invalid input may indicate authentication bypass. Status codes are part of your server's observable behaviour and need to be considered in security review.
Severity reflects how often each code appears in attack scenarios and how informative it is to attackers. Critical: codes that strongly indicate security misconfiguration when seen unexpectedly (500 leaking stack traces, 401 on resources that should be 404). High: codes that affect security posture or user trust (403 forbidden patterns, 502 bad gateway exposing infrastructure). Medium: codes with notable but contextual security relevance (301/302 redirects, 429 rate limiting). Low: standard informational responses with minimal security implication (200, 304). Severity is contextual — a 200 on a sensitive endpoint without auth is a critical bug, not a low-severity success.
Status codes leak information. Returning 401 on /admin/.htpasswd tells the attacker the file exists and is auth-protected. Returning 404 on /admin/.htpasswd tells them the file probably does not exist. Returning 403 on /backup/ tells them backup directories are common enough to be blocked specifically. Username enumeration attacks rely on different status codes (or response timings) for valid vs invalid usernames. The principle: return the same code for "exists but inaccessible" and "does not exist" — usually 404 — to avoid leaking enumeration signals.
401 Unauthorized: Authentication required and not provided (or invalid). The resource exists; you need to log in. 403 Forbidden: Authentication provided but you lack authorisation. The resource exists; you cannot access it even logged in. 404 Not Found: The resource does not exist (or you cannot tell whether it exists). For security-sensitive paths, returning 404 even for authenticated-but-forbidden access is sometimes recommended to avoid leaking that the resource exists at all. The exact choice depends on threat model — sometimes you want users to know access exists; sometimes you want it invisible to anyone unauthorised.
A 500 response by itself is just "server error". The risk is the response body — if your server is in debug/development mode, the 500 page often includes the full stack trace, file paths, database query that failed, framework version, and sometimes credentials in environment variables. This is a goldmine for attackers — internal paths to target, framework version to look up CVEs for, query syntax to refine SQL injection. Production servers should return generic 500 pages with no internal information. Detailed errors should go to your logs only.
Triage by code. Lots of 401s usually means brute-force authentication attempts or misconfigured client. Lots of 403s often means scanner traffic probing for restricted paths. Lots of 404s commonly means scanners enumerating common paths (/wp-admin, /.env, /backup.zip, /admin.php). 429 spikes mean rate-limit hits — could be legitimate or could be a sign of an attacker hitting your throttling. Pattern matters more than count: 1000 404s for /random-paths from one IP looks like scanning; 1000 404s for /missing-image.jpg from many IPs looks like a deployment problem.
Status codes themselves are unchanged across HTTP versions — 200, 404, 500 mean the same thing in HTTP/1.1, HTTP/2, and HTTP/3. The protocols differ in transport mechanics (multiplexing, header compression, encryption) but the application-layer status code semantics are stable. Some new codes were added (like 425 Too Early for replay-attack protection in 0-RTT TLS), but the bulk of the catalog is identical across versions.
No special "API only" codes — APIs use the standard HTTP status code set. But certain codes have stronger conventions in API contexts: 401 specifically for "no/invalid token", 403 for "valid token but insufficient scope", 422 Unprocessable Entity for "valid format but failed validation rules" (vs 400 for "malformed request"), 429 for rate limiting (often paired with Retry-After header). Returning the right code matters more in APIs because clients react programmatically to the code; web pages can show error messages but API clients need correct codes to handle errors.
Yes. 301 (Permanent Redirect) tells browsers and search engines to update bookmarks/indexes to the new URL — clients cache the redirect aggressively. 302 (Found / Temporary Redirect) tells them this redirect is temporary and should not be cached. For HTTP→HTTPS upgrades, use 301 (you want the upgrade cached and HSTS-locked); for short-term maintenance redirects, use 302. Wrong choice can persist incorrect routing for months because browsers cached the 301 — if you redirect HTTP→HTTPS with 302 instead of 301, every browser re-checks every time, hurting performance and downgrade-attack resistance.
Yes — and you should for sensitive paths. Common patterns: return 404 instead of 401/403 for security-sensitive paths to hide their existence from unauthenticated users; return generic 500 pages without stack traces in production; rate-limit 429 responses with appropriate Retry-After headers; use 401 with WWW-Authenticate header to trigger browser auth dialogs only where intended. Web servers and frameworks let you customise per-route — Nginx with `error_page`, Apache with `ErrorDocument`, application frameworks with their own error handlers. Customisation is part of security configuration, not just UX polish.