TLS & Certificate Cutover

Context

TLS is the layer that turns a routing change into an outage. Every other part of a cutover degrades gracefully — a stale DNS answer serves an old page, a missing redirect serves a 404 — but a certificate that does not validate produces a full-page browser interstitial that most visitors will not click through, and a handshake failure that non-browser clients reject outright with no message at all. This work sits inside the DNS Configuration & Hosting Cutover sequence and has to be complete before any traffic is shifted, because the certificate has to be valid on the new origin before anything resolves to it.

The awkwardness is a circular dependency. Most automated certificate issuance proves domain control by answering a challenge at the domain you are certifying — which, before cutover, still points at the legacy origin. Solving that ordering problem is what most of this page is about, and it is why the DNS-01 challenge and pre-staged certificates feature so heavily: both let you obtain a valid certificate for a hostname that does not yet resolve to the host presenting it.

The second recurring theme is that TLS failures are unevenly visible. A missing intermediate certificate is invisible in every browser, because browsers cache issuers from previous sessions and fetch missing ones on demand, and glaringly fatal to mobile applications, payment integrations, and anything using a strict HTTP client. The result is a migration that appears healthy to everyone testing it in a browser and is broken for a category of traffic nobody thought to check.

Certificate readiness ahead of the DNS switch A certificate issued via a DNS-01 challenge and installed on the new origin before any record changes, so the handshake already succeeds at the moment traffic is shifted. The certificate must be valid before anything resolves to it DNS-01 challenge no traffic needed Certificate issued full chain retained Installed on new origin verified by IP DNS switched handshake already works an HTTP-01 challenge here would be answered by the legacy origin — which is why it cannot be used to certify the new one Test the new origin by IP with an SNI override before the switch, so the first real request is not the first request the certificate has served. A TLS failure at cutover has no graceful degradation — the visitor sees an interstitial, and non-browser clients see nothing at all.
DNS-01 breaks the circular dependency: it proves control of the name without needing the name to point at the host being certified.

Pre-flight Checks

Establish what is currently served and what the new origin will serve, well before the window.

  • Record the current certificate’s subject, SANs, issuer chain, and expiry: openssl s_client -connect legacy.example.com:443 -servername legacy.example.com </dev/null | openssl x509 -noout -subject -issuer -dates.
  • Enumerate every hostname that must be covered — apex, www, API subdomains, asset hosts, and anything referenced by a third-party integration.
  • Confirm the current Strict-Transport-Security header, including max-age, includeSubDomains, and whether the domain is on the browser preload list.
  • Verify you can complete a DNS-01 challenge on the zone (API access, or the ability to add _acme-challenge TXT records).
  • Check certificate transparency logs for existing certificates on the domain so a forgotten wildcard does not surprise you.
  • Confirm the new origin’s TLS termination point — origin, load balancer, or CDN — and whether the CDN requires its own certificate as well as the origin’s.

TLS Readiness Checklist:

Execution Steps

1. Enumerate Every Hostname That Needs Coverage

Do this first, because every later step operates on the list it produces and a hostname omitted here is a hostname that will present a certificate error at cutover with no obvious cause. Treat the enumeration as an artefact to be reviewed rather than a note somebody keeps.

1. Enumerate Every Hostname That Needs Coverage

Build the list from the DNS zone and the crawl inventory rather than from memory. Certificates fail on the hostname nobody listed — an asset subdomain referenced only in CSS, an API host called by a mobile client, a legacy www variant that still receives traffic. Cross-check the zone’s A, AAAA and CNAME records against the hostnames appearing in the Crawl Baseline Generation export, and add anything found in either.

Decide between a SAN certificate listing each name and a wildcard covering a level. Wildcards are convenient and cover names you have not thought of, which is both their advantage and their risk: a wildcard private key compromises every subdomain at once, and some environments prohibit them for that reason. Where the hostname set is stable and small, explicit SANs are easier to audit.

Include the hostnames you are about to retire as well as the ones you are adopting. During a domain change both names have to serve valid TLS simultaneously — the legacy domain keeps answering so its redirects can be followed, and a redirect served over a failed handshake is a redirect nobody receives. Teams routinely certify the new domain thoroughly and let the legacy certificate lapse a month later, which silently breaks the mechanism that was carrying their remaining traffic across.

2. Issue Against the New Origin Before Cutover

Use a DNS-01 challenge so issuance does not depend on the hostname already resolving to the new host. This is the step that resolves the circular dependency described above, and it is why zone API access appears in the prerequisites — an HTTP-01 challenge would be answered by the legacy origin, certifying the wrong server entirely. The mechanics are covered in Issuing Certificates Before DNS Cutover.

Install the certificate on the new origin and test it there, by address, before anything resolves to it. A handshake against the new IP with an SNI override exercises the entire TLS path — certificate, chain, private key, cipher configuration — while the site is still served entirely by the legacy origin, which means a failure at this point costs nothing.

3. Serve the Complete Chain

The distinction that matters here is between what a browser needs and what the protocol requires. A server is expected to present the leaf certificate together with every intermediate needed to build a path to a trusted root; browsers are unusually forgiving about omissions because they cache issuers across sites and can fetch a missing one on demand. Nothing else in the client population is that generous, so “it works in Chrome” is evidence about Chrome rather than about the configuration.

3. Serve the Complete Chain

Configure the origin to present its intermediates, not just the leaf certificate. A missing intermediate is the single most common TLS defect after a migration and the hardest to notice, because browsers paper over it using cached or fetched issuers while strict clients reject it outright. Verify with openssl s_client -showcerts and confirm the chain terminates at a root the client population trusts. The cross-layer specifics are in Validating Certificate Chains Across CDN and Origin.

Check the CDN separately from the origin. Where an edge terminates TLS for visitors and re-establishes it to the origin, there are two certificates and two chains, and either can be incomplete independently of the other. The edge-facing one affects your visitors; the origin-facing one affects whether the edge can reach you at all.

Count the certificates the server presents rather than trusting the configuration. Most servers accept a leaf-only file without complaint and serve exactly what they were given, so the difference between a correct and an incomplete chain is invisible in the config and obvious in the handshake. One openssl s_client -showcerts piped to a grep -c answers it definitively, and it is worth doing after every certificate deployment rather than only the first.

4. Align the HSTS Policy Before You Need It

Strict-Transport-Security is a promise browsers remember, and it cannot be withdrawn from a browser that has already cached it. If the legacy origin issued a long max-age, returning visitors will refuse to connect over HTTP to the new host regardless of what the new host says — which is correct behaviour and also means a certificate problem becomes a hard outage rather than a warning. The failure modes and the safe sequencing are covered in Avoiding HSTS Lockout During Migration.

Never enable preload in the same window as a migration. Preload entries are compiled into browsers and are slow to remove, so a preloaded domain whose TLS is not yet correct on the new origin has no fallback at all for a substantial share of visitors.

Never let a wildcard and an explicit certificate for the same hostname both exist without knowing which one the server presents. Both are valid, both will satisfy a browser, and they typically have different expiry dates and different renewal automation — so the one that lapses first may or may not be the one in use, and the failure appears without warning. Pick one, remove the other from the server configuration, and note the decision alongside the certificate inventory.

5. Prove Renewal on the New Host

A certificate that was issued manually to unblock a cutover expires ninety days later with nobody watching. Configure and run the renewal path on the new origin before the window closes — not merely install the automation, but force a renewal and confirm it succeeds end to end, including reloading the server so the new certificate is actually served. Wire the expiry into the same monitoring that covers the rest of the migration, and confirm the DNS credentials the renewal depends on are not a personal token belonging to whoever set it up.

Configs / Commands

The commands below establish, in order: what the legacy origin currently serves, whether the new origin’s certificate and chain are correct before any traffic reaches it, and whether the policy headers agree across both.

Capture the legacy certificate and chain as a rollback reference:

# Subject, issuer and validity of what is live today — keep this output
openssl s_client -connect legacy.example.com:443 \
  -servername legacy.example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates

Test the new origin by IP before DNS points at it:

# --resolve forces the connection to the new host while sending the real SNI
curl -sIv --resolve www.example.com:443:203.0.113.10 \
  https://www.example.com/ 2>&1 | grep -Ei 'subject|issuer|SSL certificate|HTTP/'

Confirm the full chain is served, not just the leaf:

# Expect at least leaf + intermediate; a lone certificate is an incomplete chain
openssl s_client -connect 203.0.113.10:443 \
  -servername www.example.com -showcerts </dev/null 2>/dev/null \
  | grep -c 'BEGIN CERTIFICATE'

Nginx — serve the full chain and a conservative HSTS policy:

# ssl_certificate must be the fullchain file, not the leaf-only cert.pem
ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Start short during the migration window; raise once the cutover is proven
add_header Strict-Transport-Security "max-age=300" always;
Where each TLS failure is visible and where it is not Four TLS defects compared by whether a browser surfaces them, whether a strict HTTP client does, and the traffic category each one silently breaks. The browser is the least sensitive client you have Defect In a browser In a strict client Breaks Expired certificate interstitial hard failure everything Missing intermediate usually fine hard failure apps, payments, APIs Hostname not in SANs interstitial hard failure that hostname only Self-signed at origin never seen fails on strict origin pull the CDN, eventually Rows two and four are the dangerous ones: they look healthy to everyone testing manually and fail for traffic nobody is watching.
Test with at least one non-browser client before declaring TLS ready — curl without a trust override is enough to catch both.

Certificate transparency logs are worth checking before you begin. Every publicly-trusted certificate issued for your domain is recorded there, which means the logs will tell you about the wildcard somebody obtained two years ago for a subdomain nobody remembers, and about any certificate issued by a party you did not authorise. Both are useful to know before a migration: the first may already cover hostnames you were about to certify again, and the second is a security finding rather than a migration one.

Validation

Confirm each of these against the new origin before the record changes, and again afterwards through the public hostname.

Two independent TLS connections when a CDN terminates A visitor negotiating TLS with the CDN edge, which then negotiates a second, separate TLS connection to the origin, meaning two certificates and two chains must each be valid. A CDN in the path means two certificates, not one Visitor browser or app CDN edge edge certificate Origin origin certificate Application served content The edge certificate is what visitors validate; the origin certificate is what lets the edge reach you at all. Either can be incomplete independently of the other, and an origin fault is invisible until strict origin verification is switched on. Certify both, and check both with openssl before the cutover rather than after.
A valid edge certificate over a broken origin one works until somebody tightens the origin pull settings — then everything fails at once.

Rollback Triggers

TLS faults are among the few migration failures with no partial degradation, so the thresholds are correspondingly tight — there is no equivalent of a slightly slower page or a marginally worse redirect.

  • Any certificate warning presented to a real visitor on a monitored hostname triggers an immediate DNS reversion.
  • TLS handshake failure rate above 0.5% sustained for five minutes.
  • A non-browser integration reporting certificate validation failure, regardless of browser behaviour.
  • Certificate expiry inside seven days with renewal not yet proven on the new host.
  • HSTS discovered to be preloaded while the new origin’s certificate is not yet valid — abort before any traffic shifts.

One organisational note before the questions below. Certificate renewal is the migration task most likely to be orphaned, because it succeeds silently for months and then fails once, loudly, long after everybody has moved on. Give it an owner and an alert at least thirty days before expiry — not seven, which is too late to chase a credential held by somebody on leave — and include the renewal credential in whatever inventory the organisation keeps of secrets that must outlive their creator.

FAQ

Why not just copy the certificate and key from the legacy server? You can, and for a hosting move where the domain is unchanged it is often the fastest route — but it carries the private key across a boundary and inherits an expiry date somebody else was tracking. If you do it, transfer the key over an encrypted channel, confirm file permissions on the destination, and set up independent renewal on the new host immediately rather than relying on the legacy automation that will be decommissioned.

Does the CDN’s certificate replace the origin’s? No — they are separate connections and both need to be valid. The visitor’s browser validates the edge certificate; the edge validates the origin’s when it fetches. An origin with an expired or self-signed certificate can still serve traffic through an edge configured to ignore it, which works until somebody enables strict origin verification and everything fails at once. Certify both properly.

How short should the HSTS max-age be during a migration? Short enough that a mistake expires quickly — a few minutes is reasonable for the window itself. The point is that HSTS is remembered by the client, so a long policy set immediately before a cutover commits every visitor who loads a page in that period. Lower it in advance, keep it low through the window, and restore the long value once the new origin has served cleanly for a soak period.

What breaks if the intermediate certificate is missing? Browsers usually will not, which is the problem. They cache intermediates from earlier sessions and can fetch missing ones via the authority information access extension, so the site looks fine to everyone testing it manually. Strict HTTP clients, mobile applications, payment gateways, and server-to-server integrations generally do neither and simply fail the handshake — producing an outage that is invisible to the people investigating it.

Should certificates be issued per hostname or as one SAN certificate? One certificate covering the set is simpler to deploy and to reason about, and it means a single renewal to monitor rather than several. Split them where the hostnames have genuinely different lifecycles or different owners — an API host managed by another team, for instance — since a shared certificate couples their renewal schedules to yours.

Related

← Back to DNS Configuration & Hosting Cutover

Explore Sub-topics