Skip to main content

Troubleshooting: DOMAIN_NOT_FOUND (404)

Your branded console is supposed to load at a custom domain — app.acme.example instead of orbit.devotel.io — and the page renders with the plain Orbit look, or a pre-render lookup fails with a 404 and code DOMAIN_NOT_FOUND:
Three public lookup surfaces return this code for the same root cause — no registered custom-domain record in the active state matches the host:
  • GET /api/v1/public/resolve-domain?host=… — the host-to-organization lookup the dashboard runs up-front on every request whose Host is not the platform domain.
  • GET /api/v1/public/resolve-org-domain?org_id=… — the reverse lookup that sends a subaccount user home to their branded origin right after sign-in.
  • GET /api/v1/public/branding?host=… — the pre-auth branding lookup that renders your logo, colors, and dashboard name on the sign-in, signup, and invite screens of the custom domain.
Knowing which surface returned the 404 narrows the cause, but the fix is always on the custom-domain record itself.
When a lookup misses, the platform degrades instead of breaking: the console falls back to the neutral default theme, branded sign-in lands on orbit.devotel.io, and nothing your customers are doing stops working. That is the difference between a 404 you need to fix and a ticket you need to file — this page walks the self-serve cases first.

Cause table

List your organization’s custom domains with GET /api/v1/organization/domains and match the row’s status against the causes below. The statuses and their lifecycle — pending → verifying → active / failed — are explained in Custom domains and managed SSL.

Decision checklist

Work through these in order before you change anything:
  1. Reproduce the 404. curl "https://api.orbit.devotel.io/api/v1/public/resolve-domain?host=app.acme.example" with the exact host from the browser’s address bar. A 200 returns the { organization_id, tenant_id } pair and the console will load with your branding; a 404 returns DOMAIN_NOT_FOUND.
  2. List the claims. GET /api/v1/organization/domains — find the row whose domain equals the host character-for-character. No row means the domain was never claimed. A row with status pending, verifying, or failed means resolution is by-design 404 until it activates.
  3. Check the DNS record. The CNAME must point at the exact cname_target the claim returned, with no substitute or old value still present. Flattened or chained CNAMEs resolve as long as the chain terminates at that target.
  4. Re-verify once. POST /api/v1/organization/domains/{domainId}/verify after any DNS change. One verify is enough — re-issuing every few minutes does not speed certificate issuance.
  5. Remember the fallback. While the lookup 404s, sign-in, the dashboard, and any API on the host still work under the neutral default theme; your team is not locked out.

What NOT to do

  • Do not delete and re-claim the domain while it is verifying. Issuance started the moment the CNAME matched; tearing the record down mid-flight discards it and pushes activation back out by the full provisioning window.
  • Do not point the CNAME at something else and back. Every change re-opens the provisioning window; the publish-once-then-wait pattern is the fastest path.
  • Do not retry-loop the public endpoints. A 404 DOMAIN_NOT_FOUND is a lookup miss, not a transient failure — the same host 404s identically every time until the domain activates. Those endpoints are rate-limited per IP and short edge-cached, so looping buys nothing.
  • Do not claim the apex domain and expect subdomains to resolve. Each host (app.acme.example, console.acme.example) is its own claim row.
  • Do not file a ticket for a pending domain whose CNAME has never published. The platform cannot verify DNS you have not created.

When to escalate

Escalate to support@devotel.io when:
  • The row has sat in verifying for more than 24 hours with the CNAME unchanged and correctly pointed.
  • The row is failed and the error field does not describe a DNS problem (for example, an issuer-side or platform-side failure).
  • The lookup still 404s after the domain reached active, and the two-minute edge-cache window has passed.
Include in the ticket:
  • The exact hostname you claimed and the exact host query that 404s
  • The domain id and current status from GET /api/v1/organization/domains
  • The request_id from meta.request_id on a 404 response, if you have one
  • Confirmation that the CNAME points at the cname_target the claim returned (paste the record)