# Cloudflare Pages custom domain: HTTPS, CAA and fixes

> Cloudflare Pages custom domains with HTTPS: apex vs subdomain DNS, the CAA records Cloudflare needs, and how to fix a domain stuck on Verifying.

Source: https://ssl.sh/guides/cloudflare-pages-custom-domain/
Last updated: 2026-11-10

Cloudflare Pages issues and renews the certificate for a custom domain by itself. After you add the domain in the Pages project, Cloudflare validates it over HTTP and issues a certificate from one of its partner CAs: Let's Encrypt, Google Trust Services or SSL.com.

An apex domain such as `example.com` must be a Cloudflare zone on the same account. A subdomain can stay on any DNS provider with a CNAME to `<project>.pages.dev`. Steps follow Cloudflare's documentation as of November 2026; `my-site.pages.dev` and `example.com` are examples.

## At a glance

| Question | Cloudflare Pages |
|---|---|
| CA for automatic certificates | Let's Encrypt, Google Trust Services or SSL.com (Cloudflare picks) |
| Validation | HTTP validation of the custom domain |
| Apex (`example.com`) | Must be a Cloudflare zone; Cloudflare creates the CNAME |
| `www` and other subdomains | `CNAME` to `my-site.pages.dev` (any DNS provider) |
| CAA must allow | `letsencrypt.org`, `pki.goog; cansignhttpexchanges=yes`, `ssl.com` |
| Wildcard custom domain | Not described in the Pages docs; each hostname is added separately |
| Upload your own certificate | No upload in Pages; zone-level custom certificates are for Business and Enterprise |
| Custom domains per project | 100 (Free), 250 (Pro), 500 (Business and Enterprise) |

## Step 1: Add the domain in the Pages project

Add the hostname in the Pages dashboard before you create any DNS record:

1. Go to **Workers & Pages** and select your Pages project.
2. Open **Custom domains** and select **Set up a domain**.
3. Enter the hostname and select **Continue**.

If you create a CNAME to `my-site.pages.dev` without associating the hostname in the Pages dashboard first, the hostname does not resolve to your project and visitors get a `522` error.

## Step 2: Create the DNS records

**Apex domain.** Add `example.com` as a zone in your Cloudflare account and change the nameservers at the registrar to the two Cloudflare nameservers you are given. Once the zone is active, Pages creates the CNAME record for you when you confirm the domain.

**Subdomain on external DNS.** Add a CNAME at your DNS provider:

| Type | Name | Content |
|---|---|---|
| `CNAME` | `shop.example.com` | `my-site.pages.dev` |

If the zone is already on Cloudflare, the record is added automatically. On an Enterprise zone, release any zone hold before adding the domain, because a hold prevents the custom domain from activating.

**`www` and the apex together.** Add the apex as the custom domain and redirect `www` to it. Cloudflare's guide uses a Bulk Redirect from `www.example.com` to `https://example.com` (status `301`, with path and query preserved) plus a proxied placeholder record for `www`:

| Type | Name | IPv4 address | Proxy status |
|---|---|---|---|
| `A` | `www` | `192.0.2.1` | Proxied |

The placeholder address is never contacted; the proxy answers with the redirect. If you prefer to serve the site on both names, add `www.example.com` as a second custom domain instead.

## Step 3: Check CAA records

If you publish CAA records that do not allow Cloudflare's CAs, the domain cannot get a certificate. The Pages documentation gives this set:

```dns
example.com.  300  IN  CAA  0 issue "letsencrypt.org"
example.com.  300  IN  CAA  0 issue "pki.goog; cansignhttpexchanges=yes"
example.com.  300  IN  CAA  0 issue "ssl.com"
example.com.  300  IN  CAA  0 issuewild "letsencrypt.org"
example.com.  300  IN  CAA  0 issuewild "pki.goog; cansignhttpexchanges=yes"
example.com.  300  IN  CAA  0 issuewild "ssl.com"
```

Keep any CA you use elsewhere on the domain as an extra `issue` record. Cloudflare's debugging guide notes that missing CAA entries are most likely when Universal SSL is disabled or when the domain uses an external DNS provider. Test with the [CAA checker](https://ssl.sh/tools/caa-checker/).

## Wildcards and your own certificate

The Pages documentation only covers adding individual hostnames, so plan one custom domain per name. At zone level, Universal SSL on a full setup covers the apex and first-level subdomains; deeper names need Total TLS or an advanced certificate.

Pages has no field for uploading a certificate. Cloudflare's [custom certificates](https://developers.cloudflare.com/ssl/edge-certificates/custom-certificates/) are a zone-level feature meant for Business and Enterprise customers, and Cloudflare does not renew them for you. If you need a certificate from a particular CA for a Pages site, ask Cloudflare whether it applies to your Pages hostname before you buy one.

## Verify

An active custom domain presents a certificate from one of Cloudflare's partner CAs for the exact hostname. Check it with the [SSL checker](https://ssl.sh/tools/ssl-checker/) or from a terminal:

```bash
curl ssl.sh/example.com
```

Then confirm the certificate and the issuing CA:

```bash
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -issuer -subject -ext subjectAltName -dates
```

The issuer will be Let's Encrypt, Google Trust Services or SSL.com. All three are fine; do not pin to one of them.

## Renewal

There is nothing to renew by hand. Cloudflare manages issuance and renewal; for Universal SSL it documents 90-day certificates with renewal starting 30 days before expiry. What can break it is DNS: if you point the hostname somewhere else, the Pages custom domain becomes inactive, and pointing it back means errors until it is active again. To divert traffic temporarily, use an Origin Rule or a redirect rule rather than editing the record. Public certificates are capped at 200 days today and at 100 days from March 15, 2027, which Cloudflare's 90-day certificates already meet. Add the domain to [ssl.sh monitoring](https://ssl.sh/monitor/) (in development) to catch an inactive domain early.

## Troubleshooting: stuck in Verifying

When a domain does not move past the **Verifying** stage, work through Cloudflare's checklist.

**Blocked HTTP validation.** Pages must reach an HTTP endpoint on the domain. Cloudflare Access, a redirect, a Worker, a WAF custom rule or a Client-Side Security content rule in the way stops validation. Test the challenge path:

```bash
curl -s -o /dev/null -D - https://example.com/.well-known/acme-challenge/randomstring
```

A `302` to `cloudflareaccess.com` means Access is intercepting. Disable that Access policy (or redirect, or Worker) until the domain is verified, then turn it back on.

**Missing CAA records.** Run `dig CAA example.com` on the apex (or on the subdomain zone). A single `0 issue "amazon.com"` record, for example, blocks every Cloudflare CA; add the six records above. See [CAA record prevents issuance](https://ssl.sh/errors/caa-record-prevents-issuance/).

**Zone hold.** Release it during setup and reinstate it once the domain is active.

**Errors only on the custom domain.** If `my-site.pages.dev` works and the custom domain does not, your zone settings (caching, rules) apply to the proxied record. Switch the record to **DNS only** to confirm, then review the zone configuration.

If the domain is still verifying after 15 minutes with all of the above checked, contact Cloudflare support.
