Why a custom domain doesn't start routing until you've proven you own it
Subdomain takeover is one of those vulnerability classes that sounds obscure until you’ve seen it happen once: a team points status.example.com at a third-party service, stops using that service, forgets to remove the DNS record, and months later someone else claims that same service slot and now controls what status.example.com serves — complete with a valid certificate, to anyone who visits. It’s a well-documented bug class precisely because the failure mode is so easy to create by accident and so easy to miss until it’s exploited.
Where the default protection actually is
Every app starts with a working, certificated URL with nothing to configure: https://<name>.<server-ip>.sslip.io — a free DNS trick (sslip.io resolves based on the IP embedded in the hostname itself) that needs no DNS record of your own at all, so there’s nothing to misconfigure on day one.
Adding a real custom domain is where the takeover risk usually lives, and it’s where the actual check happens: alongside the DNS record you add (an A record to the server’s IP, or CNAME for a subdomain), a second TXT record gets requested — _railyard-verify.<domain> → railyard-verify=<token>. Checked automatically every 30 seconds, or on demand with Check now. The certificate and routing do not start until that TXT record is actually found. Someone pointing a domain they don’t control at an app — the exact mechanic behind a takeover — simply never gets past “unverified,” because they can’t produce a token they were never given.
The states that make this legible, not just enforced
A domain shows one of five states, and each one answers a different question honestly instead of collapsing everything into a generic “pending”: unverified (the TXT record hasn’t been found yet), pending (ownership confirmed, certificate not issued yet), live (actually serving traffic), unrouted (verified, but the app hasn’t redeployed since adding it — a redeploy is what actually routes it), or misconfigured (certificate issuance failed, with Check now showing why). Knowing which of these a domain is in is the difference between “it’s probably fine” and actually knowing what’s left to do.
Wildcards get the same check, scaled up
Adding *.example.com routes every subdomain to the app at once instead of adding each one by hand — genuinely useful for a multi-tenant product giving each customer their own subdomain. The ownership check scales with it: it probes railyard-check.example.com rather than every possible subdomain, so the wildcard can’t be claimed without controlling the actual zone. By default each subdomain gets its own certificate the first time it’s visited; adding a DNS credential gets one certificate covering the whole wildcard instead, a tradeoff of setup complexity against certificate count that’s worth choosing deliberately rather than defaulting into.
The www/bare-domain pair, handled together
Tick Also add the www/bare-domain version and both get added and verified together, redirecting to whichever one you later mark primary — a detail that matters because the half of this pair someone forgets is usually the one that ends up unmonitored and, eventually, the one a takeover actually targets.
Full reference: Domains and HTTPS.