Troubleshooting
Common failure modes — stuck verification, propagation delays, conflicts, and drift.
A connection is stuck in pending_ownership or verifying
The ownership TXT at _customdomain-challenge.<hostname> hasn't been seen with
the expected value yet. Verification is value-checked — the record must
match exactly (see Ownership and setup types).
- Confirm the TXT record was published at the exact name from
ownership_challenge.name, not the bare hostname. - DNS propagation can take minutes to hours depending on the record's previous TTL and the customer's resolver/registrar.
- Call
POST /v1/connections/{id}/verifyto force an immediate re-check, or wait for the background worker (WORKER_ENABLED=1) to pick it up automatically.
409 HostnameConflict on create
Exactly one active claim per hostname exists globally (verified /
issuing_cert / live). Either the same tenant already has a connection for
this hostname, or a different tenant does. Archive
the existing connection before retrying if it's stale.
402 QuotaExceeded
The plan's connect limit has been reached for the current period. The error
carries limit, plan, and upgrade_url — see
Plans & quotas.
Propagation never finishes / connection is stalled
records:check reports each desired record's propagated state and
observed_value. Common causes:
- The customer's DNS provider hasn't applied the record yet (TTL wait).
- A delegated credential write failed (check the provider's dashboard for the actual record set) — see DNS providers and Provider setup for provider-specific gates (e.g. GoDaddy's account-tier gate, Namecheap's IP allowlist).
- The customer edited or removed a record after adding it.
A live domain shows drifted
The background worker re-checks live domains on an interval; if records stop
resolving to their intended values it transitions to drifted and fires
domain.drift. Have the customer restore the records, or re-apply them via a
delegated credential.
Certificate not issuing
Certificates are issued on demand at the TLS handshake, gated by
GET /internal/ask returning allow: true — which only happens once the
connection is verified or later. If the edge is misconfigured
(EDGE_ISSUER, CONTROLPLANE_URL), see
Self-hosting → Configuration.
Widget shows "session expired"
Widget tokens expire after 60 minutes (see Widget tokens). Mint a fresh token server-side and reopen the widget.