200 OK Does Not Mean Your Service Works
If you have ever built a health check, you have probably written something close to this: const res = await fetch ( url , { method : ' GET ' , signal : AbortSignal . timeout ( 10000 ) }); const isUp = res . status === 200 ; I ran a version of that for a while. It is wrong in at least five ways, and every one of them bit me while building an outage tracker for Indian services. This is a write-up…
A commonly used health check code snippet assumes a "200 OK" response from a server means the service is functioning correctly. However, this assumption is flawed in several ways, as discovered during the development of an outage tracker for Indian services. This piece explains the five key mistakes made by treating a 200 response as proof of full health, along with alternative monitoring approaches.
Firstly, a 200 response only indicates the server sent a reply, but it provides no insight into whether the user's intended action succeeded. For instance, a bank's homepage might load in 400 milliseconds, while UPI payments could fail due to issues at the switch. The problem lies in treating a 200 response as an indication of overall health, which is inaccurate.
Secondly, a 403 response does not necessarily mean the service is down. Some websites deliberately block automated requests through bot protection, web application firewalls (WAF), rate limiting, or geo-geographical restrictions. In India, this is common on government and travel portals like IRCTC. A naive checker would mark such sites as permanently down, leading users to ignore the tool within a week.
In this case, a 403 indicates the server is alive but refusing the specific request, while a 500 indicates a genuine service failure.
Thirdly, when a service is behind a Content Delivery Network (CDN), a cached page could still return a 200 status even if the origin has failed. This situation results in a false positive, as the check is monitoring the CDN rather than the application itself. Moreover, some applications return a 200 response with an error message in the body, such as a maintenance page or a React shell displaying "Something went wrong." In these scenarios, the status line alone is insufficient to determine the application's actual state.
Fourthly, a single check performed from a single location offers limited information. It only reveals the path between the server and the check's location. Indian outages are frequently regional, such as a telecom fault affecting specific PIN codes, a state portal collapsing during election results, or an ISP route failure in a particular city.
A local check might appear fine or even globally dead, which are both misleading perspectives. Monitoring multiple regions provides a more comprehensive view of the service's health.
Lastly, users are often more reliable indicators of service availability than synthetic checks. For consumer-facing services, crowd reports can be a more accurate signal than automated checks. If a user experiences a payment failure, they can accurately report the issue. Therefore, the recommended approach is to prioritize crowd reports over server checks, with the server check serving as a secondary measure.
When a check cannot reach a service but no user reports a problem, the status page should display a message indicating that the service could not be reached, rather than labeling it as down. This distinct distinction helps reduce noise and provides a more accurate representation of the service's status.
In summary, a health check should report four states: reachable (the service is accessible), refused (the service is alive but rejects the request), broken (the service is unable to fulfill the user's request), or unknown (the service status is indeterminate). Rendering a 403 as down and treating a 200 response as proof of full health is misleading.
To improve monitoring accuracy, consider asserting on content within the response, using multi-region probing, and incorporating user reports as primary signals. Additionally, be transparent about the monitoring methodology to maintain credibility.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.