From a0861ab04fc107062415fbc655dda6e175db3293 Mon Sep 17 00:00:00 2001 From: Tom McLoughlin Date: Mon, 18 May 2026 10:18:08 +0100 Subject: [PATCH 1/2] docs: add zero-downtime migration guide for custom hostnames --- .../zero-downtime-migration.mdx | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/zero-downtime-migration.mdx diff --git a/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/zero-downtime-migration.mdx b/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/zero-downtime-migration.mdx new file mode 100644 index 000000000000000..ca3f8722de233b8 --- /dev/null +++ b/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/zero-downtime-migration.mdx @@ -0,0 +1,175 @@ +--- +pcx_content_type: how-to +title: Zero-downtime migration +description: Migrate end customers from another CDN to Cloudflare for SaaS without any downtime by pre-validating custom hostnames before cutting over DNS. +products: + - cloudflare-for-saas +sidebar: + order: 3 +head: + - tag: title + content: Zero-downtime migration - Custom Hostname Validation +--- + +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. + +## Overview + +The migration sequence is: + +1. Create the custom hostname via API. +2. Pre-validate hostname ownership using an HTTP token or a DNS TXT record. +3. (Optional) Pre-issue the TLS certificate using Delegated DCV. +4. Confirm the hostname is `active`. +5. Update the end customer's CNAME - traffic cuts over with no downtime. + +--- + +## Step 1: Create the custom hostname + +Call the [Create Custom Hostname](/api/resources/custom_hostnames/methods/create/) endpoint. Note the `ownership_verification` and `ownership_verification_http` fields in the response - you will need them in the next step. + +```bash title="Create custom hostname" +curl https://api.cloudflare.com/client/v4/zones/{zone_id}/custom_hostnames \ + --header "Authorization: Bearer " \ + --header "Content-Type: application/json" \ + --data '{ + "hostname": "app.example.com", + "ssl": { + "method": "http", + "type": "dv", + "settings": { + "http2": "on", + "min_tls_version": "1.2" + } + } + }' +``` + +```json title="Example response (truncated)" +{ + "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. + +--- + +## Step 2: Pre-validate hostname ownership + +Choose the method that fits your end customer's situation. + +### Option A: HTTP token (end customer does not control DNS) + +Use this method when the end customer cannot update their authoritative DNS, or when you want to handle the verification yourself. + +1. Copy the `http_url` and `http_body` from the `ownership_verification_http` object in the response above. + +2. Have the end customer serve the `http_body` value at the `http_url` path on their origin server. For example, in nginx: + + ```nginx title="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 a `200` status and the exact token value in the body. + + :::note + If you can serve this token on behalf of your customers (for example, via a shared origin infrastructure), you can complete verification without any action from the end customer. + ::: + +3. Wait a few minutes for Cloudflare to crawl the token. The hostname status will move from `pending` to `active` once ownership is confirmed. + +### Option B: TXT record (end customer controls DNS) + +Use this method when the end customer can add a DNS record at their authoritative DNS provider. + +1. Copy the `name` and `value` from the `ownership_verification` object in the response above. + +2. Have the end customer add a `TXT` record at their DNS provider: + + | Type | Name | Value | + | ---- | ---- | ----- | + | `TXT` | `_cf-custom-hostname.app.example.com` | `0e2d5a7f-1548-4f27-8c05-b577cb14f4ec` | + +3. Wait a few minutes for Cloudflare to detect the record. The hostname status will move to `active` once ownership is confirmed. + +4. Once the hostname is active, the end customer can remove the TXT record. + +--- + +## Step 3: Pre-issue the TLS certificate (optional) + +By default, the TLS certificate issues and deploys after the end customer's CNAME points to your fallback origin. To avoid any TLS errors during cutover, pre-issue the certificate before updating DNS using one of these methods: + +- [**Delegated DCV**](/cloudflare-for-platforms/cloudflare-for-saas/security/certificate-management/issue-and-validate/validate-certificates/delegated-dcv/) - Place a one-time CNAME record at your authoritative DNS that allows Cloudflare to validate and auto-renew certificates without any further customer action. Best when you control a shared DNS zone. +- [**TXT validation**](/cloudflare-for-platforms/cloudflare-for-saas/security/certificate-management/issue-and-validate/validate-certificates/txt/) - Have the end customer add a `TXT` record to their authoritative DNS. Required for wildcard custom hostnames. +- [**Manual HTTP validation**](/cloudflare-for-platforms/cloudflare-for-saas/security/certificate-management/issue-and-validate/validate-certificates/http/#http-manual) - Serve a DCV token file at a `/.well-known/` path on the origin. No action required from the end customer. + +:::note +Hostname validation (`ownership_verification`) and certificate validation (`ssl.validation_records`) use separate tokens and API fields. Completing hostname pre-validation does not automatically pre-issue the certificate - you must also complete one of the above certificate validation methods if you want a pre-issued certificate. +::: + +--- + +## Step 4: Confirm the hostname is active + +Before updating DNS, verify that both the hostname and certificate are ready. + +```bash title="Get custom hostname details" +curl https://api.cloudflare.com/client/v4/zones/{zone_id}/custom_hostnames/{custom_hostname_id} \ + --header "Authorization: Bearer " +``` + +```json title="Example response (truncated)" +{ + "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. + +--- + +## Step 5: Update the end customer's CNAME + +Once both statuses are `active`, 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. + +--- + +## Related resources + +- [Pre-validation methods](/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/pre-validation/) +- [Certificate validation methods](/cloudflare-for-platforms/cloudflare-for-saas/security/certificate-management/issue-and-validate/validate-certificates/) +- [Validation status](/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/validation-status/) +- [Getting started with Cloudflare for SaaS](/cloudflare-for-platforms/cloudflare-for-saas/start/getting-started/) From 54099bdfe8141479c4323fe40cfc4c9572eb7839 Mon Sep 17 00:00:00 2001 From: Tom McLoughlin Date: Tue, 19 May 2026 14:19:37 +0100 Subject: [PATCH 2/2] docs: address feedback on zero-downtime migration guide --- .../hostname-validation/backoff-schedule.mdx | 2 +- .../domain-support/hostname-validation/index.mdx | 2 ++ .../zero-downtime-migration.mdx | 16 +++++++++------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/backoff-schedule.mdx b/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/backoff-schedule.mdx index 360ff1b151ff9d5..98d4114f35d67d3 100644 --- a/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/backoff-schedule.mdx +++ b/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/backoff-schedule.mdx @@ -5,7 +5,7 @@ description: Retry schedule for custom hostname validation over a seven-day peri products: - cloudflare-for-saas sidebar: - order: 3 + order: 4 head: - tag: title content: Backoff schedule | Hostname validation diff --git a/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/index.mdx b/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/index.mdx index 1a581f306bf5098..2f8b6b8a596ab69 100644 --- a/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/index.mdx +++ b/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/index.mdx @@ -35,6 +35,8 @@ For production traffic, the hostname should have `status: active`, `ssl.status: Custom hostnames using another CDN are not compatible with Cloudflare for SaaS. Since Cloudflare must be able to validate your customer's ownership of the hostname you add, if their usage of another CDN obfuscates their DNS records, hostname validation will fail. +If your customer needs to migrate from another CDN with no downtime, refer to [Zero-downtime migration](/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/zero-downtime-migration/), which uses pre-validation to validate the hostname and optionally pre-issue the certificate before DNS cutover. + ## Related resources diff --git a/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/zero-downtime-migration.mdx b/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/zero-downtime-migration.mdx index ca3f8722de233b8..b3bd1f972029832 100644 --- a/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/zero-downtime-migration.mdx +++ b/src/content/docs/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/zero-downtime-migration.mdx @@ -13,13 +13,11 @@ head: 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. -## Overview - -The migration sequence is: +## Migration sequence 1. Create the custom hostname via API. 2. Pre-validate hostname ownership using an HTTP token or a DNS TXT record. -3. (Optional) Pre-issue the TLS certificate using Delegated DCV. +3. Pre-issue the TLS certificate before DNS cutover. 4. Confirm the hostname is `active`. 5. Update the end customer's CNAME - traffic cuts over with no downtime. @@ -115,11 +113,11 @@ Use this method when the end customer can add a DNS record at their authoritativ --- -## Step 3: Pre-issue the TLS certificate (optional) +## Step 3: Pre-issue the TLS certificate -By default, the TLS certificate issues and deploys after the end customer's CNAME points to your fallback origin. To avoid any TLS errors during cutover, pre-issue the certificate before updating DNS using one of these methods: +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**](/cloudflare-for-platforms/cloudflare-for-saas/security/certificate-management/issue-and-validate/validate-certificates/delegated-dcv/) - Place a one-time CNAME record at your authoritative DNS that allows Cloudflare to validate and auto-renew certificates without any further customer action. Best when you control a shared DNS zone. +- [**Delegated DCV**](/cloudflare-for-platforms/cloudflare-for-saas/security/certificate-management/issue-and-validate/validate-certificates/delegated-dcv/) - A one-time CNAME record delegates `_acme-challenge` to 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**](/cloudflare-for-platforms/cloudflare-for-saas/security/certificate-management/issue-and-validate/validate-certificates/txt/) - Have the end customer add a `TXT` record to their authoritative DNS. Required for wildcard custom hostnames. - [**Manual HTTP validation**](/cloudflare-for-platforms/cloudflare-for-saas/security/certificate-management/issue-and-validate/validate-certificates/http/#http-manual) - Serve a DCV token file at a `/.well-known/` path on the origin. No action required from the end customer. @@ -153,6 +151,10 @@ curl https://api.cloudflare.com/client/v4/zones/{zone_id}/custom_hostnames/{cust Wait until both `result.status` and `result.ssl.status` are `active` before proceeding. If either is still `pending`, wait and poll again. +:::note +If you skipped Step 3, `ssl.status` will remain `pending` until after DNS cutover. Proceed to Step 5 once `result.status` is `active`. During this window, requests to the hostname will result in a TLS error until the certificate finishes issuing. Pre-issuing the certificate in Step 3 avoids this entirely. +::: + --- ## Step 5: Update the end customer's CNAME