The Parking Page Passed the Health Check
The publish run for a new tool’s domain came back with one word: LIVE. I had not changed the nameservers yet. Nothing of mine was reachable at that name, and the script that said otherwise was reading a real HTTP 200 from a real server.
What the script asked
The publish step is small. It adds the ingress rule to the tunnel that fronts my public services, adds the DNS routes, and then probes the public URL to confirm the name reaches the app. A timer re-runs the whole thing until the probe passes, then disables itself, so a domain that is not ready yet becomes ready on its own once the last manual step lands. The probe was a request to /healthz on the new name, and a 200 was a pass.
The registrar was still pointing the domain at its own parking page. A parking page is a catch-all. It answers every path with the same page and the same status, because its entire job is to make sure something is there when anyone types the name. It answered /healthz with 200, as it would have answered /anything. The script asked “does something answer at this name”, and a registrar exists to make the answer to that question yes.
So the timer disabled itself, satisfied, on a domain that served a page selling the domain.
Ask for something only the app can say
The fix is to stop asking whether something answers and start asking whether the right thing answers. The probe now requires the body of the health response, the app’s own JSON with its own fields, and a 200 carrying anything else is a fail. The install step arms the retry timer on the same test. And the not-live message names the one step that remains, because the zone and the routes now exist and the only thing between the name and the app is a nameserver change at the registrar that no script of mine can make.
That is what the timer is doing as I write this: firing, probing, failing correctly, and re-arming. It will keep failing until I change the nameservers, and when I do, it will pass on the next tick and switch itself off, which is the behaviour I wanted from it on the first evening.
A shape I had already met
I wrote in July about a catch-all on one of my own servers that answered a request for a stylesheet with the homepage, and how a browser took that 200 at face value and cached HTML at a CSS address. This is the same shape one layer out. A catch-all does not know what you asked for. It knows that answering is its job. Any check that reads a catch-all’s answer as confirmation is confirming only that the catch-all exists, and a catch-all is the one thing on the internet you can always count on to exist.
The general form is short. A liveness check has to ask a question that only the live service can answer. A status code is not such a question; every server has one. A specific body, with a field the service computes, is.
The domain is still parked tonight. The probe knows.