HTTP Status Codes That Matter for Monitoring
Know which HTTP status codes should page you: 401, 403, 429, and the 5xx class, plus how to handle redirects and health endpoints.

Not every non-200 response is an incident, and not every 200 means everything is fine. Treating "status code != 2xx" as your only alerting rule produces both false alarms and missed outages. Understanding what each class of status code actually signals lets you build alerting rules that page you for real problems and stay silent for expected behavior.
The Core Problem: 2xx Isn't Always "Healthy"
A load balancer health check might return 200 while the backend it's routing to is completely broken. Conversely, a 429 Too Many Requests from a third-party API might be entirely expected and self-resolving. Status-code-based alerting only works when you know which codes deserve a page, which deserve a log entry, and which are just noise.
Status Code Reference for Monitoring
| Code | Meaning | Should it page? | Notes |
|---|---|---|---|
200 | OK | No (but verify body) | Combine with body assertions |
201 | Created | No | Expected for successful POST |
204 | No Content | No | Common for DELETE endpoints |
301/302 | Redirect | Depends | Verify final destination and count of hops |
304 | Not Modified | No | Expected for conditional GETs |
400 | Bad Request | No (client bug) | Log, don't page - usually a client-side issue |
401 | Unauthorized | Yes if unexpected | Could mean expired credentials or auth outage |
403 | Forbidden | Yes if unexpected | May indicate WAF blocking legitimate traffic |
404 | Not Found | Depends | Fine for optional resources, bad for core endpoints |
429 | Too Many Requests | Warn, not page | Expected under rate limiting; watch for sustained spikes |
500 | Internal Server Error | Yes | Always page |
502 | Bad Gateway | Yes | Upstream/backend unreachable |
503 | Service Unavailable | Yes | Overload or maintenance - confirm which |
504 | Gateway Timeout | Yes | Backend too slow to respond |
Redirects (3xx): Verify the Destination, Not Just the Hop
A 301 or 302 isn't a failure, but an unexpected redirect chain often signals a misconfiguration - for example, HTTPS silently downgrading to HTTP, or a domain redirecting to an expired staging environment.
curl -sL -o /dev/null -w "%{http_code} %{url_effective} %{num_redirects}\n" \
https://example.com
Alert if:
- The number of redirects exceeds an expected count (usually 0 or 1)
- The final
url_effectivedoesn't match the expected canonical domain - A redirect moves from HTTPS to HTTP
401 and 403: Auth Failures That Look Like Outages
These codes are easy to misclassify. A 401 on a public homepage check is alarming; a 401 on an API endpoint you're deliberately probing without credentials is expected. The fix is to scope your assertions per-check:
- For authenticated endpoints, an unexpected
401/403usually means an expired token, revoked API key, or a broken auth service - page on this. - For endpoints you intentionally test unauthenticated (to confirm auth is enforced), expect
401/403and alert if you don't get it.
curl -s -o /dev/null -w "%{http_code}\n" https://api.example.com/v1/admin
# Expect 401 here - alert if you get 200 instead
429: Rate Limiting Is a Signal, Not Always a Fire
A 429 from a third-party dependency you're calling is normal under load - it means the throttle is doing its job. What matters is the trend:
- A handful of
429s per hour: informational, not actionable - A sustained rate of
429s over minutes: your request volume has outgrown your quota, or a retry loop is hammering the endpoint
Track 429 rate as a metric rather than a boolean pass/fail, and alert on a rate threshold, not on the first occurrence.
The 5xx Family: Always Take These Seriously
| Code | Typical Cause |
|---|---|
500 | Unhandled exception in application code |
502 | Reverse proxy can't reach the backend |
503 | Server overloaded or intentionally in maintenance mode |
504 | Backend took too long to respond |
All of these should page immediately, but distinguish 503 during a planned deploy from 503 during an unplanned outage - a maintenance window should suppress alerts, not require someone to manually acknowledge a known event every time.
Health Endpoints vs Real Endpoints
A dedicated /healthz endpoint checks whether the process is running and often whether its immediate dependencies (database, cache) respond. It does not guarantee that a real user request through the full request path - load balancer, auth middleware, business logic, downstream API calls - succeeds.
Best practice: monitor both.
/healthz- fast, cheap, high-frequency (every 30–60s), tells you "is this instance alive"- Real endpoints (
/api/v1/orders,/checkout) - full assertions on status, latency, and body, run less frequently but with more depth
See our deeper guide on health check endpoint design for how to structure /healthz correctly, and pair it with full uptime monitoring against your actual user-facing endpoints.
Building an Alerting Rule Set
A reasonable default policy:
- Page immediately on any 5xx from a critical endpoint
- Page on unexpected 401/403 for authenticated endpoints
- Warn (don't page) on 429 unless sustained above a rate threshold
- Ignore expected 3xx unless the destination or hop count changes
- Suppress alerts during declared maintenance windows
- Always combine status code checks with response body assertions on real endpoints
FAQ
Should a 404 ever trigger a page?
Only for endpoints expected to always exist. A 404 on /api/v1/users/{id} for a deleted user is normal; a 404 on your homepage or a core API route means something is badly broken and should page.
Is 429 a monitoring failure?
Not by itself. Treat it as a rate metric. A single 429 is often the throttle working as designed; a sustained rate of 429s indicates a capacity or client-behavior problem worth investigating.
Why does my load balancer show healthy while users report errors?
Your load balancer health check likely only verifies the process is up, not that dependencies or business logic work. Layer in checks against real endpoints with body assertions, not just the LB's shallow health probe.
How do I avoid paging during planned maintenance?
Declare a maintenance window in your monitoring tool ahead of the deploy so alerts are suppressed for that period, and re-enable full alerting immediately afterward - don't leave suppression on longer than the actual window.
What's the difference between monitoring status codes and full uptime monitoring?
Status code checks are one signal among several. Full uptime monitoring, like ServerInspector provides, combines status, latency, body assertions, SSL validity, and multi-region checks into a single view of whether a service is actually usable.