Apex domains
Why a CNAME cannot live at a zone apex, what DoDomain supports at the apex today, and the patterns that work when your infrastructure only speaks CNAME.
Sooner or later a customer will type acme.com where you expected app.acme.com. If your product is reached by hostname — a CNAME to your edge — that request cannot be satisfied, and the failure is in DNS itself, not in DoDomain. This page is the honest account of what works at the apex, what does not, and what to do about it.
Why a CNAME cannot sit at the apex
A CNAME record cannot coexist with any other record at the same name — RFC 1034 §3.6.2, restated as an absolute in RFC 2181 §10.1. The apex of a zone is exactly the name that must carry that zone's SOA and NS records. Other data therefore always exists there, so a CNAME can never be added.
This applies to the apex of any zone, not only to registrable domains: if eu.acme.com is delegated as its own zone, eu.acme.com is an apex too.
What DoDomain supports at the apex
POST /api/v1/sessions accepts five record types — A, AAAA, CNAME, TXT, MX — and a host of "@" (an empty string and the domain itself mean the same thing) resolves to the domain itself. So this is an apex record:
{ "type": "A", "host": "@", "value": "203.0.113.10" }A, AAAA, TXT, and MX at the apex all work, and verification queries them at the apex against authoritative nameservers like any other record. What differs is which connect path a session gets:
| Connect path | Apex records |
|---|---|
| Cloudflare one-click (tier 1) | A, AAAA, TXT, MX at @ — written through the user's OAuth grant and read back from Cloudflare before the session finalizes. |
| Domain Connect one-click (tier 2) | None. The two templates we publish express exactly two shapes: a non-apex CNAME, and an ownership TXT at the fixed host _dodomain-challenge. Anything else — including every apex record — can't be compiled, so the flow shows manual records. |
| Guided manual (tier 3) | A, AAAA, TXT, MX at @, for every provider. The flow already knows each provider's own apex convention and tells the user to enter @, to leave the name blank, or to type the domain, whichever that provider's panel expects. |
Tier 3 is the universal fallback, so an apex session always has a working path — it just doesn't get a one-click path unless the customer is on Cloudflare.
CNAME at the apex
The API does not reject { "type": "CNAME", "host": "@" } at session creation. The only record checks that run there are the accepted type set and MX's required priority, so the call returns 200 with a connectUrl. It will not get your customer connected, and here is exactly where it stops:
- Domain Connect one-click refuses it. The recipe compiler throws before anything is written —
CNAME recipe requires a non-apex host (CNAME cannot sit at the zone apex)— so the one-click button never renders, and calling/domain-connect/startdirectly answers400 invalid_requestwith that message. The flow falls back to manual records. - Guided manual shows the user an instruction their provider will reject, or which their provider will quietly reinterpret as its own alias feature (below).
- Verification asks the authoritative nameservers for a
CNAMErecord at that name. Providers offering an apex alias answer apex queries withA/AAAArecords — that is what makes an alias resolvable by ordinary clients at all — so theCNAMElookup finds nothing and the session never reachesverified.
Treat "no CNAME at the apex" as a rule you enforce in your own UI, before you mint the session.
Detecting an apex before you create the session
POST /api/v1/domains/check returns both the domain you submitted and the zone that owns
records for it. When the two are equal, the customer gave you a zone apex — that is the moment to
ask for a subdomain instead, while they still have the input focused.
Provider-side alternatives
Several DNS providers offer a non-standard record — variously ALIAS, ANAME, or CNAME flattening — that behaves like a CNAME in the zone editor but is resolved by the provider's own nameservers, which then answer the apex query with the target's addresses. There is no RFC for this; each provider implements it under its own name, with its own limits.
Two things are worth being blunt about:
- DoDomain cannot create one for your customer. No tier writes an ALIAS/ANAME record — it is not one of the five record types a session can request. Where a provider offers the feature, the customer configures it in their provider's panel themselves.
- An alias serves your hostname's current addresses. If a customer aliases their apex at your edge hostname and you later change that hostname's IPs, the apex follows — but a DoDomain session that pinned a specific
Avalue will only stay verified while that value is what the alias resolves to. If you rely on alias records, expect drift and let the monitor'sconnection.failedtell you about it.
Which providers offer one
DoDomain detects 22 DNS providers by nameserver. The table below records only what each provider's own public documentation states about pointing a zone apex at a hostname — each provider name links to the page it was read from. Where we could not settle it from a provider-owned page, the row says so rather than guessing.
| Provider | Apex → hostname | What their own docs say |
|---|---|---|
| Cloudflare | Yes | CNAME flattening — a CNAME at the zone apex, which Cloudflare resolves to addresses when answering queries. |
| DNSimple | Yes | ALIAS record, built specifically because "you cannot use a CNAME record on your root domain". |
| Gandi | Yes, with conditions | ALIAS record — LiveDNS nameservers only, and their page warns it breaks DNSSEC on the bare domain. |
| Hostinger | Yes | ALIAS record. |
| Name.com | Yes | ANAME (alias) record — "Unlike CNAME records, ANAMEs can be placed next to other records". |
| Namecheap | Yes | ALIAS record — "if you wish to alias the root domain to another service". |
| Porkbun | Yes | ALIAS record — usable "on the root domain and alongside other DNS records". |
| Squarespace Domains | Yes | ALIAS record, with @ as the name for the root. |
| Vercel | Yes | ALIAS — apex only, and the target domain must return A/AAAA records. |
| WordPress.com | Yes | ALIAS record. |
| AWS Route 53 | Not for this | Alias records do work at the zone apex, but AWS documents their targets as selected AWS resources (CloudFront, ELB, S3 website endpoints and similar) or another record in the same hosted zone — not an arbitrary vendor hostname. |
| OVHcloud | Different mechanism | No ALIAS/ANAME. They document an HTTPS/SVCB record in alias mode for the apex, which only clients implementing that record type follow. |
| DigitalOcean | No | Their DNS API's record-type list contains no ALIAS or ANAME. |
| IONOS | No | Their DNS settings page lists the record types on offer; none is an ALIAS or ANAME. |
| NameSilo | No | Their DNS Manager's addable record types contain no ALIAS or ANAME. |
| STRATO | No | States plainly that CNAME entries are available at subdomain level only. |
| Wix | No | Their manageable record types contain no ALIAS or ANAME. |
| Bluehost | Check with provider | No page on their own site settles it either way. |
| DreamHost | Check with provider | No page on their own site settles it either way. |
| GoDaddy | Check with provider | No page on their own site settles it either way. |
| HostGator | Check with provider | No page on their own site settles it either way. |
| one.com | Check with provider | No page on their own site settles it either way. |
Two readings of "No" are mixed in there and it is worth knowing which you have: STRATO says so in prose and DigitalOcean's API enumerates its record types exhaustively, while IONOS, NameSilo, and Wix are "No" because each publishes the list of record types it offers and no alias-type record appears on it. None of them publishes a sentence denying apex aliasing outright.
Read this table as a starting point for a support conversation, not as a contract. It reflects each provider's documentation as of August 2026, and providers add features without telling us.
Recommended patterns
1. Ask for a subdomain (the default)
app.acme.com, links.acme.com, status.acme.com. One CNAME, supported by every provider, every tier, and the one-click paths. Validate the input in your own form: if the domain the customer typed equals its own zone, reject it with a message that says what to do — "Enter a subdomain, like app.acme.com" — rather than accepting it and failing later in the connect flow.
2. Serve the apex from A/AAAA records
If your infrastructure has stable, publicly documented IP addresses (an anycast edge, a load balancer with reserved IPs), request A/AAAA at "@" and the apex works everywhere, including one-click apply on Cloudflare. The cost is real and permanent: those addresses become a contract with every connected customer, and changing them means re-connecting all of them.
3. www plus a redirect at the provider
Have the customer point www.acme.com at you with a CNAME — fully supported, one-click included — and set up apex-to-www forwarding in their provider's panel, if that provider offers domain forwarding.
Be clear with yourself about the split: the CNAME at www is what the session verifies and what the monitor watches. The redirect at the apex is the provider's feature — DoDomain neither creates it nor monitors it, so a customer who removes it will break their apex without any connection.failed firing.
Don't promise the apex you can't deliver
If your product is reachable only by hostname, the honest answer to "can I use my root domain?" is
a subdomain, or an alias record the customer sets up themselves at a provider that supports one.
Accepting an apex CNAME request and letting it fail in the connect flow costs your support team
far more than refusing it in the form.