Troubleshooting
Common failure modes — stuck connections, propagation delays, rail errors, and drift.
A connection is waiting in pending
pending means we have not yet seen the DNS records in public DNS. There is
no deadline — a pending connection is re-checked every minute at first, then
every few minutes, and after three days every six hours, for as long as it
takes. Add the records whenever you're ready and the domain connects on its
own. After three days the console shows "We haven't detected the DNS records
yet" so you know what's outstanding; that is a diagnosis, not a failure.
To check right now instead of waiting: Re-check now on the domain page
(POST /v1/connections/{id}:recheck). It reports each record's verdict.
Common reasons the records never show up:
- The record was added at the wrong place. Records must be added at the
provider that serves the domain's nameservers (
dig NS your-domain.com), which is not always the registrar you bought the domain from. - Root domain on GoDaddy, Namecheap or Name.com. These panels have no
ALIAS/ANAME type, so the console shows A records to our apex addresses
instead of a CNAME. Add exactly those A records at
@. (A CNAME at@is rejected by the panel, or breaks your email.) - The domain doesn't resolve at all — unregistered, or registered but never delegated to a DNS provider. The connect flow now refuses these up front with an explanation; fix the delegation at your registrar first.
- A hosting platform's subdomain (
something.vercel.app,*.netlify.app,*.github.io, …) can't be connected: the platform owns its DNS. Use a domain you control.
My domain points at Custom Domain but shows a connection / certificate error
If you added the DNS records after the connection had been marked failed, visitors' browsers reach our edge but the connection isn't serving yet. Since this release the edge treats that traffic as your signal: the connection is re-entered into verification automatically and goes live on the next check (usually within a minute or two). You can also press Re-check now. If it stays failed, the domain already has another active connection in the same application — finish or delete that one.
"Failed" — what it means now
A connection only reaches failed when records we wrote ourselves never
propagated (24h), or a credentialed write was rejected. Never because you were
slow. Finish setup on the domain page resumes a failed connection (same
row, history kept); adding the same domain again does the same thing rather
than creating a duplicate.
The verification email never arrived / the link expired
Verification links last one hour and work once. On the Check your email screen use Resend the link; an expired link lands on a page where you can request a new one. Still nothing? Check spam, then email [email protected] and we'll verify you by hand.
GoDaddy won't give me an API token
GoDaddy only issues DNS API access to accounts with 10+ domains or a paid plan. Everyone else: add the records shown in the console by hand — that path works on every GoDaddy account. GoDaddy's "sign in with GoDaddy" one-click setup also isn't available yet (it requires GoDaddy-side onboarding).
Route 53: "The security token included in the request is invalid"
You pasted temporary credentials (an access key starting with ASIA…).
Those need the third field, Session token, which the Route 53 form now has.
Permanent IAM-user keys (AKIA…) don't need it.
A connection is stuck in propagating
Records were written but aren't all resolving to their intended values yet.
- DNS propagation can take minutes to hours depending on the previous record's TTL and the customer's resolver/registrar.
- Verify the records at the provider's dashboard — a rail write can succeed at the API but land on the wrong host, or a customer may have edited them afterward.
propagatingconnections that never resolve within 24 hours transition tofailedand fireconnection.failed.
service_unavailable on a rail
POST /v1/connections/{id}/apply (and the OAuth / one-click setup starts)
return 503 service_unavailable when the corresponding engine isn't wired for
your plan or environment: no DNS provider registry, no OAuth client for the
provider (OAUTH_<PROVIDER>_CLIENT_ID/_SECRET), or no one-click signing key
(DC_SIGNING_KEY_FILE). Contact support if you hit this on the hosted service.
Rail B write failed
apply returns an error carrying the provider's message when the scoped token is
wrong-scoped, expired, or the zone doesn't match. Confirm the token has DNS
edit rights on the exact zone you passed, and mind provider gates (GoDaddy
account tier, Namecheap IP allowlist) — see
Provider setup.
OAuth (Rail C) never returns
- PopupBlockedError — the browser blocked the authorize window; trigger
oauth:startfrom a direct user gesture. - The callback only postMessages to a
return_originon the server's allowlist (OAUTH_ALLOWED_RETURN_ORIGINS) — a mismatched origin silently drops the result. - An expired or replayed
statereturns400from the callback; re-runoauth:startto get a fresh one.
A live domain stopped working
The lifecycle doesn't demote a live connection, but
Monitor fires domain.record_missing
when a live domain's records stop resolving. Have the customer restore the
records (or re-apply them via a rail). Run POST /v1/monitor:check to compare on
demand.
Certificate not issuing
Certificates are issued on demand at the TLS handshake, gated by
POST /internal/ask returning { approved: true } — which happens only once the
connection is propagating or live. If the edge can't reach the gate, check
EDGE_ASK_URL, EDGE_ASK_SECRET, and EDGE_ACME_PROD/EDGE_ACME_EMAIL.
Widget shows "session expired"
Widget tokens expire (default 60 minutes — see Widget tokens). Mint a fresh token server-side and reopen the widget.