How to Monitor a Site That Only Accepts Traffic From Certain Countries
Geo-restricted uptime monitoring means running your checks from a location that the site actually serves, and treating the location of the check as part of the test itself. If you point a single monitor at a geo-blocked site from the wrong country, you are not measuring uptime, you are measuring the block page, and every result it produces is noise.
The core problem is that "the site is up" is not a property of the site, it is a property of the site as seen from somewhere. A CDN or an origin with a country filter will return a real page to one client and a refusal to another, often with a perfectly healthy status code. Your job is to decide which vantage points matter, make each check declare where it is coming from, and make the monitor understand what a block looks like so it does not page you at three in the morning for a 403 that is doing exactly what it was configured to do.
Understand what the block actually returns
Before you change any monitoring, find out how the restriction is implemented, because the failure mode you need to whitelist depends entirely on this. There are three common shapes. The edge returns a redirect to a different host or path, the edge returns a flat 403 or 451, or the edge returns a 200 with a holding page or a challenge script. The last one is the dangerous case, because a naive monitor sees a healthy status code and reports success while the real users in the blocked region see nothing useful, and, more importantly, a real outage in a served region can hide behind the same code.
Ask the origin directly from a machine you control in each region. The simplest probe is a bare request with no browser behaviour, so you see the raw decision the edge makes rather than the rendered page.
curl -sS -o /dev/null -D - https://example.com/health \
--resolve example.com:443:203.0.113.10
HTTP/2 200
content-type: text/html; charset=utf-8
x-served-region: eu-west
cache-control: no-store
Replace the address in --resolve with the edge or origin you are testing. Look at the status line, the content-type, and any region header the edge emits. Then repeat it from a host in a country that should be blocked and compare. The difference between the two responses is your definition of "blocked", and you should write it down, because the monitor config has to encode it.
Make the check declare its own location
The most reliable way to avoid false alarms is to run the check from a vantage point you control in the target country, rather than hoping a public monitor node happens to be there. A small instance in the region, a scheduled job on a box you already run there, or a container in a regional cloud region all work. What matters is that the check is honest about where it sits and that you know the address space it uses.
If the restriction is enforced on source IP, the exit address of your probe is the thing that gets allowed or denied, so confirm it before you trust any result. Do not assume the address you see on the box is the one the site sees; NAT, proxies and egress gateways change it. Query an address echo service from the same host and compare.
curl -sS https://ifconfig.me
203.0.113.10
curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' \
https://example.com/health
200 0.214
The second line gives you the status and total time in one shot, which is enough to feed a trivial check. If the site uses a header or a token to identify allowed clients, add it with -H, but keep that token out of logs and out of the monitor's public status page. A geo restriction enforced by a shared secret is not a geo restriction, it is an access control, and it belongs in the monitor's secret store, not in a config file committed to a repository.
Whitelist the block, not just the success
This is where most geo-restricted uptime monitoring setups go wrong. A monitor has two states, up and down, and it maps status codes onto them. If a blocked region returns 403 and your monitor treats every non-200 as down, you will get an alert for correct behaviour. You need a third state, "blocked as expected", and you need to assert it explicitly rather than ignore it, because an unexpected 200 from a blocked region can mean the filter has been misconfigured or removed.
Most monitoring tools let you define a check as a combination of conditions. The shape varies, but the logic is the same: from the blocked-region probe, expect 403 or 451, and alert if you get 200. From the served-region probe, expect 200 and a body that matches a known marker, and alert on anything else. Write the marker check as a string match on something stable, such as a line in the health endpoint, not on a marketing headline that changes.
# served region: must be 200 and contain the marker
curl -fsS https://example.com/health | grep -q 'status: ok'
# blocked region: must NOT be 200
code=$(curl -sS -o /dev/null -w '%{http_code}' https://example.com/health)
[ "$code" = "200" ] && echo "GEO FILTER MISSING" && exit 1
exit 0
Run that pair under the same scheduler and alert on either branch. The blocked-region branch is the one people forget, and it is the one that catches a CDN rule that got reordered during a deploy.
Handle CDNs that serve different regions differently
If a CDN sits in front of the site and caches per region, the same URL can legitimately return different content, different headers, or a different status depending on where the request lands. Do not monitor a single URL and assume one truth. Pick a small set of URLs that must behave consistently in each region, and monitor the region-specific behaviour rather than the page as a whole. Health endpoints are ideal because they should be identical everywhere they are served and clearly blocked everywhere they are not.
Watch the cache. A probe that hits a cached block page will keep reporting the block long after the rule changed, and a probe that hits a cached success can hide a real failure. Send a cache-busting query string or a Cache-Control: no-cache request header on the health check so you are measuring the origin and edge decision, not a stale object. Also check that the edge's own region header, if it emits one, matches the region you think you are testing from. If it does not, your traffic is being routed somewhere you did not intend, and every result after that is suspect.
Finally, keep the served-region checks in more than one place. A site that only accepts traffic from certain countries is often served from a single origin, and a monitor in one city cannot tell the difference between a regional network problem and a real outage. Two vantage points in the served set, plus one in the blocked set, gives you enough to distinguish "the site is down" from "this path to the site is down".
What to do next
Start by capturing the actual responses from one allowed and one blocked location, by hand, and write down the status codes, headers and body markers you see. Turn those observations into explicit assertions in your monitor, including the assertion that the block is still working. Then run the pair of checks for a week before you trust the alerts, and tune the thresholds and timeouts against what you observe rather than against defaults. Once the checks are stable, add a second served-region vantage point so a single network path cannot page you on its own.
