Zero-downtime migration
When an end customer is already live on another CDN, switching their CNAME to your Cloudflare fallback origin causes a brief window where Cloudflare cannot yet proxy their traffic. Pre-validation lets you verify hostname ownership and optionally pre-issue the TLS certificate before the DNS cutover, so the migration is seamless.
- Create the custom hostname via API.
- Pre-validate hostname ownership using an HTTP token or a DNS TXT record.
- Pre-issue the TLS certificate before DNS cutover.
- Confirm the hostname is
active. - Update the end customer's CNAME - traffic cuts over with no downtime.
Call the Create Custom Hostname endpoint. Note the ownership_verification and ownership_verification_http fields in the response - you will need them in the next step.
curl https://api.cloudflare.com/client/v4/zones/{zone_id}/custom_hostnames \ --header "Authorization: Bearer <API_TOKEN>" \ --header "Content-Type: application/json" \ --data '{ "hostname": "app.example.com", "ssl": { "method": "http", "type": "dv", "settings": { "http2": "on", "min_tls_version": "1.2" } } }'{ "result": { "id": "24c8c68e-bec2-49b6-868e-f06373780630", "hostname": "app.example.com", "status": "pending", "verification_errors": ["custom hostname does not CNAME to this zone."], "ownership_verification": { "type": "txt", "name": "_cf-custom-hostname.app.example.com", "value": "0e2d5a7f-1548-4f27-8c05-b577cb14f4ec" }, "ownership_verification_http": { "http_url": "http://app.example.com/.well-known/cf-custom-hostname-challenge/24c8c68e-bec2-49b6-868e-f06373780630", "http_body": "48b409f6-c886-406b-8cbc-0fbf59983555" }, "created_at": "2020-03-04T20:06:04.117122Z" }}The verification_errors field will show custom hostname does not CNAME to this zone at this stage - that is expected. The error clears once pre-validation completes.
Choose the method that fits your end customer's situation.
Use this method when the end customer cannot update their authoritative DNS, or when you want to handle the verification yourself.
-
Copy the
http_urlandhttp_bodyfrom theownership_verification_httpobject in the Create Custom Hostname response. -
Have the end customer serve the
http_bodyvalue at thehttp_urlpath on their origin server. For example, in nginx:nginx example location /.well-known/cf-custom-hostname-challenge/24c8c68e-bec2-49b6-868e-f06373780630 {return 200 "48b409f6-c886-406b-8cbc-0fbf59983555\n";}Cloudflare crawls this URL using
User-Agent: Cloudflare Custom Hostname Verification. The origin must respond with a200status and the exact token value in the body. -
Wait a few minutes for Cloudflare to crawl the token. The hostname status will move from
pendingtoactiveonce ownership is confirmed.
Use this method when the end customer can add a DNS record at their authoritative DNS provider.
-
Copy the
nameandvaluefrom theownership_verificationobject in the Create Custom Hostname response. -
Have the end customer add a
TXTrecord at their DNS provider:Type Name Value TXT_cf-custom-hostname.app.example.com0e2d5a7f-1548-4f27-8c05-b577cb14f4ec -
Wait a few minutes for Cloudflare to detect the record. The hostname status will move to
activeonce ownership is confirmed. -
Once the hostname is active, the end customer can remove the TXT record.
Pre-issuing the certificate ensures there is no TLS error during cutover. Without this step, the certificate cannot issue until after the end customer's CNAME points to Cloudflare, which means ssl.status will remain pending through the DNS change. Choose one of these methods:
- Delegated DCV - A one-time CNAME record delegates
_acme-challengeto your SaaS zone, letting Cloudflare handle all future renewals automatically. The end customer can place the delegation CNAME at their own authoritative DNS, or if you host DNS for your customers directly, you can place it at your own zone instead. - TXT validation - Have the end customer add a
TXTrecord to their authoritative DNS. Required for wildcard custom hostnames. - Manual HTTP validation - Serve a DCV token file at a
/.well-known/path on the origin. No action required from the end customer.
Before updating DNS, verify that both the hostname and certificate are ready.
curl https://api.cloudflare.com/client/v4/zones/{zone_id}/custom_hostnames/{custom_hostname_id} \ --header "Authorization: Bearer <API_TOKEN>"{ "result": { "id": "24c8c68e-bec2-49b6-868e-f06373780630", "hostname": "app.example.com", "status": "active", "ssl": { "status": "active" } }}Wait until both result.status and result.ssl.status are active before proceeding. If either is still pending, wait and poll again.
Once result.status is active (and ssl.status is active too, if you pre-issued the certificate in Step 3), have the end customer update their CNAME to point to your fallback origin:
| Type | Name | Value |
|---|---|---|
CNAME | app | fallback.yoursaaszone.com |
Traffic will begin proxying through Cloudflare as soon as DNS propagates. Because the hostname was already validated and the certificate was already issued, there is no downtime or certificate error during the transition.