CustomDomain™ docs
DNS

Root domains (apex)

Why acme.com differs from www.acme.com, what each DNS provider can hold at the root, and how CustomDomain™ connects it with ALIAS-style records or A records.

www.acme.com is a subdomain: any DNS provider can hold a CNAME there, and a CNAME pointing at edge.customdomain.ai is all a connection needs.

acme.com is the root (the apex of the zone). DNS forbids a CNAME at the root, because the root already carries the zone's SOA and NS records and a CNAME may not coexist with anything. So a root domain needs one of two things, and which one depends entirely on the DNS provider:

  • A CNAME-like record the provider offers at the root, called ALIAS, ANAME, or "CNAME flattening" depending on the panel. CustomDomain™ uses it at Cloudflare, Netlify, easyDNS and Bunny (a flattened CNAME), DNSimple, Namecheap, NS1, Porkbun, PowerDNS and Vercel (ALIAS), and Constellix and DNS Made Easy (ANAME). The connection's record set shows it as that provider's own spelling; the engine calls it APEXCNAME internally, a name you should never see in a panel.
  • Plain A records pointing at the edge's addresses, everywhere else: GoDaddy, IONOS, OVH, DigitalOcean, Name.com, deSEC (no root CNAME and no ALIAS), Route 53 (whose alias records only reach AWS resources), and most registrar panels. The console, the widget and the API show the exact A records to add.

What the widget does with a root domain

When a customer types a root domain, the widget asks before it creates anything:

  • Root and www (recommended): connects both and redirects the root to www, so acme.com and www.acme.com both work.
  • Root only: connects acme.com alone.
  • A subdomain instead: shop.acme.com or similar.

It also says how that provider points a root (with its own ALIAS-style record type, or with A records it lists). When the provider can hold neither, it offers www or a subdomain instead of a setup that cannot work. Skip the question by passing wwwRedirect: true or false to open().

What the pre-flight tells you

POST /v1/domains:check reports how a root would be pointed before anything is created:

  • apex_strategy: alias (an ALIAS-style record to a hostname), a_records (address records), or unsupported (neither is possible at this provider for this application).
  • apex_record_type: the record type to pick in the provider's panel (for example ALIAS, ANAME or CNAME), or A.
  • apex_targets: the addresses for a_records.
  • target_mode: edge, or custom when the application points its domains at its own infrastructure.
  • apex_supported: a provider fact: can this provider hold a CNAME-like record at the root at all. Reported on every check, root target or not.
  • apex_message: a this-domain verdict, present only when the record set this check ran against needs a root record the provider cannot hold, that is, exactly when an automated write would refuse. Gate your warning UI on the message, never on the flag: a subdomain connect on a provider without root support is fine, and reports apex_supported: false with no message.

The console's options and the record table already apply this: a root domain at GoDaddy gets A records, at Cloudflare gets a flattened CNAME.

Automatic rails and the root

  • Sign in with the provider (OAuth) and API key writes realize the root record in the provider's own type (ALIAS/ANAME/flattened CNAME) where one exists. Where none does, the write uses A records to the edge's addresses. An apply that would need a root type the provider cannot express is refused with apex_not_supported, the same verdict apex_message gave you at check time.
  • One-click setup (Domain Connect) applies the apex-a template (an A record to the edge's address, bound server-side) at every provider, so it needs APEX_A_TARGETS. A plain CNAME at the root is not offered as a template: the Domain Connect linter refuses one, so no provider would serve it.
  • Manual shows whichever records the provider can hold.

A domain on your own infrastructure follows the same provider rules with your hostname and apex_ipv4 in place of the edge's: an ALIAS-style record to your hostname where the provider has one, otherwise A records to apex_ipv4. Without apex_ipv4, a root at a provider with neither is refused when the connection is created (422 apex_not_supported); connect www instead.

www and the root together

Most products want both acme.com and www.acme.com to work. Create the connection for the root and set www_redirect: true: the record set gains a CNAME www → edge.customdomain.ai alongside the root record, and the edge answers the bare root with a 301 to https://www.acme.com (path and query preserved). www is the canonical host; the root always reaches it. The connection's webhook events report the redirect's state as redirection_status.

Connecting www alone is the fallback when the provider cannot hold a root record and the user won't add A records. It works at every provider; the bare root then does nothing until a root record exists.

Certificates at the root

TLS issues the same way for a root as for a subdomain: once the records resolve to the edge, issuance happens on first request. A CAA record at the root that doesn't authorize Let's Encrypt blocks issuance for the whole zone; the check reports this in advisories, as an entry of kind caa-blocks-letsencrypt, and the fix is to add a CAA record for letsencrypt.org alongside the existing ones, never to remove them. It is an advisory and not a record_conflicts entry because nothing is replaced: it never counts toward will_fallback_to_manual.

Common mistakes

The widget's live DNS check and GET /v1/connections/{id}/diagnose catch each of these and say how to fix it.

  • Typing the full domain into the Name field. Most panels add the domain themselves, so acme.com in the Name field becomes acme.com.acme.com. Use @ for the root.
  • Pasting the CNAME value as an A record, or the IP as a CNAME. The record table's Type column is exact; copy the value for that type.
  • Cloudflare with the orange cloud on for these rows. Leave them DNS only (grey cloud) or the certificate can't issue.
  • Leaving the old records in place. An old A record or an AAAA (IPv6) record at the root still sends some visitors to the previous host; remove them.
  • Expecting a root CNAME at GoDaddy or IONOS. Those panels don't have one; use the A records shown, or connect www.
  • Both a root record and a conflicting wildcard. A * record already at the provider can shadow the new one; the check lists it in record_conflicts.

See also Troubleshooting and DNS providers: what actually works today.

On this page