A Pages custom domain added by API gets stuck on 'CNAME record not set'

2 min read CloudflarePagesDNS

Attach a custom domain to a Cloudflare Pages project through the API and it can sit at pending forever. The dashboard auto-creates the DNS record; the API doesn't, and a Pages-scoped token can't either.

The symptom

I attached a custom domain to a Cloudflare Pages project over the API (POST /accounts/{id}/pages/projects/{name}/domains). It returned success, then sat at status: pending indefinitely. DNS resolved to Cloudflare, but the site returned a 522. The domain detail said it plainly: verification_data.error_message: "CNAME record not set".

What was actually happening

When you add a custom domain to a Pages project in the dashboard, Cloudflare quietly does two things: it registers the domain with the project, and it creates the DNS record that points the domain at the project (a flattened CNAME to <project>.pages.dev). The API call only does the first. So the domain is attached, but nothing in DNS routes to the project, hence “CNAME record not set,” and the 522 (DNS reaches Cloudflare’s edge, but there is no origin behind it).

The trap deepens with token scope. A Pages-only API token can attach the domain, but it cannot create the DNS record, that needs Zone → DNS → Edit, a different permission. So even when you script it, the Pages token gets you halfway and stops.

The fix

Create the DNS record yourself with a token that has DNS edit on the zone. For an apex domain whose zone is in the same Cloudflare account:

curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
  -H "Authorization: Bearer $DNS_EDIT_TOKEN" -H "Content-Type: application/json" \
  --data '{"type":"CNAME","name":"example.com","content":"my-project.pages.dev","proxied":true,"ttl":1}'

Cloudflare flattens the apex CNAME automatically. Once the record exists, the Pages domain re-validates from pending to active within a minute or two and the 522 clears. Adding the domain through the dashboard does both steps in one click, which is exactly why the dashboard “just works” and the bare API call does not.

The lesson

“Add a custom domain” in the Pages dashboard is two actions: register the domain and create its DNS record. The API only registers it, and a Pages-scoped token cannot create the DNS. If a Pages custom domain is stuck on “CNAME record not set,” add the CNAME yourself with a DNS-edit token and it goes active.

Related fixes

Discussion

Powered by GitHub. Sign in to leave a comment.