
Every response your web server sends to a browser includes an HTTP status code — a three-digit number that tells the client what happened with its request. Understanding these codes is fundamental to web development, debugging, and monitoring.
This guide covers every major status code: what it means, what causes it, and what to do about it.
HTTP status codes are grouped by their first digit:
The client (browser or API consumer) determines what to do based on the status code. A browser knows to follow a 301 redirect. An HTTP client knows to retry a 429 with backoff. Knowing what each code means helps you debug problems and build applications that handle them correctly.
The standard success response. The request was received, understood, and processed. The response body contains the requested resource.
This is what you want to see for any successful request — a webpage loading, an API call returning data, a file being served.
Returned when a POST request successfully creates a new resource. REST APIs commonly return 201 after a successful POST /resources call, often with the newly created resource in the response body and a Location header pointing to it.
The server successfully processed the request but has no content to return. Common for:
The server is delivering only part of the resource, typically in response to a Range header from the client. Used for resumable downloads and video streaming where clients request specific byte ranges.
The requested resource has been permanently moved to a new URL. Browsers and search engines should update their records and use the new URL going forward.
Common use cases:
www.domain.com to domain.com (or vice versa)301 redirects pass link equity (SEO value) to the new URL — search engines transfer ranking signals to the new location.
The resource is temporarily at a different URL. Browsers follow the redirect but don't update their bookmarks. Search engines don't transfer link equity.
Use 302 for genuinely temporary redirects: A/B testing, maintenance redirects, redirects that will change.
After a POST request, redirect the client to a different URL with a GET request. Used in the Post/Redirect/Get pattern to prevent form resubmission on page refresh.
The resource hasn't changed since the client's cached version. The server skips sending the response body — the client uses its cache. Relies on ETag or Last-Modified headers.
This is good — it means caching is working correctly and requests are faster.
Like 302 and 301 respectively, but with an important difference: the HTTP method must not change. A 307/308 redirect preserves POST, PUT, DELETE. A 301/302 typically downgrades to GET.
Use 307/308 when redirecting form submissions or API requests where the method matters.
The server can't process the request because of a client-side error — malformed syntax, invalid request message framing, or deceptive request routing.
Common causes:
Fix: Check the request format against the API documentation. Log the request body on the server side to see what's being received.
The request requires authentication, and either no credentials were provided or the provided credentials are invalid.
The name is slightly misleading — it actually means "unauthenticated" (no valid credentials), not "unauthorised" (authenticated but lacking permission, which is 403).
Common causes:
Fix: Re-authenticate and retry with fresh credentials.
The server understood the request but refuses to authorise it. The client is authenticated but doesn't have permission to access this resource.
Common causes:
Fix: Check access control configuration. Verify the user has the required permissions. See our full guide: 403 forbidden error fix.
The server can't find the requested URL. Either the resource doesn't exist or the URL is wrong.
Common causes:
Fix: Verify the URL. If the resource was moved, implement a 301 redirect. Check server routing configuration.
The HTTP method used isn't supported for this URL. The server returns an Allow header listing the supported methods.
Example: Sending a DELETE request to an endpoint that only supports GET and POST.
Fix: Check the API documentation for the correct HTTP method. Ensure your client is using the right verb.
The server timed out waiting for the request. The client took too long to send the complete request.
Fix: Check client-side timeouts, network conditions, and whether a large request body is causing the delay.
The request conflicts with the current state of the resource. Common in REST APIs when:
Like 404, but permanent — the resource was here and won't be coming back. More explicit than 404 for intentionally removed resources.
Useful for retired API versions or content that has been deliberately removed. Search engines can de-index 410 pages more quickly than 404 pages.
The request was well-formed but contained semantic errors. Common in REST APIs for:
Often returned with an error body detailing which fields failed validation.
The client has sent too many requests in a given time period — rate limiting.
The response typically includes a Retry-After header indicating when to try again.
Fix: Implement exponential backoff in your client. Reduce request frequency. Consider whether you need a higher rate limit tier.
5xx errors mean the server failed — the client's request was valid, but the server couldn't fulfil it. These are the codes that require server-side investigation.
A generic catch-all for server errors. Something went wrong server-side, but the server didn't have a more specific error to report.
Common causes:
Fix: Check server error logs. 500 errors always produce log entries — the log contains the actual cause. See 500 internal server error fix.
A server acting as a gateway (reverse proxy, load balancer) received an invalid response from an upstream server.
Common causes:
Fix: Restart the application server process. Check that it's listening on the correct port. See 502 bad gateway fix.
The server is temporarily unable to handle the request — typically due to overload or maintenance.
Common causes:
Fix: Scale resources, optimise application code, or wait for the load to subside. See 503 service unavailable fix.
A server acting as a gateway didn't receive a timely response from an upstream server.
Common causes:
Fix: Identify and optimise slow operations. Increase timeout values if the operation is legitimately slow. Add caching where appropriate. See 504 gateway timeout meaning.
If you're using Cloudflare:
These all point to problems between Cloudflare and your origin server. See dedicated guides: Cloudflare error 521, Cloudflare error 522, Cloudflare error 524.
HTTP status codes are the primary signal that uptime monitoring uses to evaluate whether your website is healthy. A monitor that receives a 200 marks the check as successful. A monitor that receives a 500, 502, or 503 — or no response at all — marks it as failed and triggers an alert.
This is why a good health check endpoint matters. Rather than checking your homepage (which involves full page rendering, database queries, and all your application logic), a dedicated /health endpoint gives monitoring tools a fast, reliable signal:
@app.route('/health')
def health_check():
return {'status': 'ok'}, 200
Domain Monitor monitors your URLs every minute from multiple global locations and alerts you the moment a non-2xx response (or no response) is detected. Create a free account and add monitors for your critical endpoints — you'll catch problems the moment they occur rather than when users report them.
For deeper monitoring guidance, see the ultimate guide to website uptime monitoring.
| Code | Meaning | Who's responsible |
|---|---|---|
| 200 | OK | — |
| 201 | Created | — |
| 204 | No Content | — |
| 301 | Moved Permanently | Server config |
| 302 | Found (temp redirect) | Server config |
| 304 | Not Modified | — (caching working) |
| 400 | Bad Request | Client |
| 401 | Unauthorized | Client (auth) |
| 403 | Forbidden | Server (permissions) |
| 404 | Not Found | URL/routing |
| 422 | Unprocessable Entity | Client (validation) |
| 429 | Too Many Requests | Client (rate limit) |
| 500 | Internal Server Error | Server (application) |
| 502 | Bad Gateway | Server (proxy/backend) |
| 503 | Service Unavailable | Server (capacity) |
| 504 | Gateway Timeout | Server (slow backend) |
A subdomain takeover lets an attacker claim your subdomain by exploiting dangling DNS records. Learn how it happens, real-world examples, and how DNS monitoring detects it.
Read moreMean time to detect (MTTD) measures how long it takes to discover an incident after it starts. Reducing MTTD is one of the highest-leverage improvements in reliability engineering.
Read moreBlack box monitoring tests your systems from the outside, the way users experience them — without access to internal code or infrastructure. Learn how it works and when to use it.
Read moreLooking to monitor your website and domains? Join our platform and start today.