EmberlyEmberly Docs

Custom Domain Internals (Cloudflare)

How embrly.ca provisions TLS for user custom domains via Cloudflare SSL-for-SaaS, and how to debug it.

Custom domains are a cloud-only feature — this page documents how the managed embrly.ca instance is configured, for staff/operator reference. It doesn't apply to self-hosted deployments; see Cloud vs. Self-Hosted.

Configuration

Cloudflare credentials are configured via Admin Panel → Settings → Integrations → Cloudflare, not environment variables:

  • API token (Zone: Read, Custom Hostnames: Edit)
  • Account ID
  • Zone ID

A CNAME record must also exist in Cloudflare pointing the target hostname (e.g. cname.embrly.ca) at the app's own hostname — this is the value users are told to point their CNAME records at.

How It Works

When a user clicks Verify on a pending domain:

  1. Emberly performs a DNS lookup to confirm the CNAME points to the configured target hostname
  2. If resolved, Emberly calls createCustomHostname on the Cloudflare Zone API
  3. Cloudflare begins SSL certificate provisioning
  4. Status is polled and persisted in customDomain.cfMeta
  5. Once active, file URLs for that user can use the custom domain

Troubleshooting

ErrorCauseFix
7003 / 7000 from CloudflareSSL-for-SaaS not enabled on the zoneContact Cloudflare Support to enable it
CNAME not resolvingDNS propagation in progressWait 5–10 minutes and retry
Certificate stuck pendingOwnership TXT record missingAdd the TXT record shown in cfMeta.ownership_verification
Rate limited (429)10 verification attempts per 10 minWait before retrying

Rate Limits and Backoff

Emberly applies exponential backoff via cfBackoffCount and cfPauseUntil fields to avoid hammering the Cloudflare API during repeated failures.

Debugging cfMeta

The customDomain.cfMeta column stores the full Cloudflare API response for a domain. Inspect it directly to diagnose certificate issuance issues:

bunx prisma studio
# → CustomDomain table → cfMeta column

On this page