How to Set Up Cloudflare Enterprise DNS on AWS Route 53

Updated October 19, 2026 · 7 min read

Use this guide when your domain’s DNS is hosted in AWS Route 53 and you are activating it on the xCloud Cloudflare Enterprise add-on. Route 53 cannot put a CNAME at the root, and its ALIAS records cannot point at an external hostname, so the root reaches Cloudflare through two A records. Add the proof records first, wait until the domain shows Active, and only then cut traffic over.

If your DNS is somewhere else, use the matching guide: Google Cloud DNS, Namecheap, or Cloudflare without an xCloud integration.

Prerequisites

What you are creating

Open the domain’s Cloudflare Enterprise page in xCloud. For a site, open the site’s Cloudflare Enterprise page. For an external domain, go to Addons → Cloudflare Enterprise Addons, open the row’s actions menu, and select Manage. The Ownership Verification panel lists every record. Copy the values from the panel: the token, certificate target, and edge addresses are specific to your domain and environment.

Purpose Record Moves live traffic?
Ownership proof TXT at _cf-custom-hostname No
Certificate proof CNAME at _acme-challenge, ending in .dcv.cloudflare.com No
Routing Two A records at the root, CNAME at www Yes

The first two prove control and are safe to add at any time. The routing records move traffic. For Route 53, the panel shows the two root A records as required records and warns that they must wait until the domain is Active.

Activate the domain

1. Add the two proof records

In the Route 53 console, open Hosted zones, select the domain’s zone, and create:

Record name Type Value TTL
_cf-custom-hostname TXT The ownership token from the panel, in double quotes 300
_acme-challenge CNAME The certificate target from the panel 300

Route 53 expects TXT values in double quotes, for example "abc123-...".

The _acme-challenge CNAME delegates certificate validation to Cloudflare, so it keeps working through every renewal. If the panel offers two _acme-challenge TXT records instead, add those. Never add both forms, because they cannot share a name.

Expected result: The website keeps serving from its current host, and the proof rows in the panel change to Verified after propagation.

2. Verify and wait for Active

Select Verify Records in the Ownership Verification panel. If your team has a Cloudflare integration connected, the same button reads Verify & Add Records. To refresh the status, use Refresh Status in the page header for an external domain, or open the domain row’s actions menu and select Refresh status for a site.

Expected result: The domain status changes to Active. Do not add the root A records before this point.

3. Lower the TTL on the records you will replace

If you can, lower the TTL on the current root and www records to 300 a day before the cutover. The cutover takes as long as the TTL of the record you replace.

4. Cut the root and www over

After the domain shows Active, update the routing records:

Record name Type Value TTL
(blank, for the root) A Both edge addresses from the panel, one per line 300
www CNAME The www target from the panel 300

Put both A values in one record set. If an A record or ALIAS already exists at the root, edit it and replace its values rather than creating a second record set.

You will not add the root CNAME. Route 53 rejects a CNAME at the apex with RRSet of type CNAME with DNS name example.com. is not permitted at apex, and the A records replace it.

Expected result: The routing rows change to Verified, and the site serves through Cloudflare Enterprise.

Optional: cut over with the AWS CLI

Save this as change-batch.json and replace the example values with the values from your panel:

{
  "Comment": "Cloudflare Enterprise cutover",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "example.com.",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [
          { "Value": "203.0.113.10" },
          { "Value": "203.0.113.11" }
        ]
      }
    },
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com.",
        "Type": "CNAME",
        "TTL": 300,
        "ResourceRecords": [{ "Value": "edge.example.net" }]
      }
    }
  ]
}
aws route53 change-resource-record-sets \
  --hosted-zone-id Z0123456789ABCDEFGHIJ \
  --change-batch file://change-batch.json

aws route53 get-change --id /change/C0123456789ABCDEFGHIJ

UPSERT replaces the existing record set, which avoids the “invalid set of changes” error that CREATE returns when a record already exists. get-change reports INSYNC once Route 53 has applied the change.

Verify it worked

Query in this order:

dig +short NS example.com                          # the zone you edited serves this domain
dig +short TXT _cf-custom-hostname.example.com     # ownership proof
dig +short CNAME _acme-challenge.example.com       # certificate proof
dig +short A example.com                           # the two edge addresses
dig +short CNAME www.example.com                   # the www target
curl -sSI https://example.com | grep -iE 'server|cf-ray'

server: cloudflare with a cf-ray header means the edge is serving the site. Also check https://www.example.com and the site’s critical paths.

If a record you just created still reads as missing, query a public resolver with dig @1.1.1.1 +short TXT _cf-custom-hostname.example.com. A resolver that asked before the record existed can cache the empty answer for the zone’s SOA minimum, often 15 to 30 minutes.

Troubleshooting

Symptom Likely cause Fix
RRSet of type CNAME ... is not permitted at apex Route 53 cannot hold a CNAME at the root. Use the two A records instead.
The request contains an invalid set of changes A record already exists at that name. Edit the existing record set and replace its values, or use UPSERT.
Records never verify, but they look correct You edited a hosted zone that is not delegated. Route 53 can hold several zones for one domain. Compare dig +short NS example.com with the zone’s Hosted zone details and edit the matching zone.
The panel says Cloudflare cannot verify the root while it points at Cloudflare The root A records were added before the domain was active. Point the root back at your origin, select Verify Records, and add the A records again after Active.
The root and www return Cloudflare error 1001 The A records were added to a hostname that was not yet active. Restore the origin A record, wait for Active, then cut over again.

FAQ

Can I use a Route 53 ALIAS record at the root?

No. A Route 53 ALIAS can only target AWS resources or another record in the same hosted zone, not an external hostname. Use the two A records shown in the panel.

Why does Route 53 say the request contains an invalid set of changes?

A record already exists at that name. Edit the existing record set and replace its values, or use UPSERT in the AWS CLI, instead of creating a second record set.

When can I add the root A records?

Only after the domain shows Active. Cloudflare will not verify a domain that already points at its own addresses.

Do I need the root CNAME the panel mentions?

No. Route 53 cannot hold a CNAME at the root, so the two A records are the root’s routing record.