Validating Certificate Chains Across CDN and Origin
Problem Statement
When a CDN sits in front of your site there are two TLS connections, not one, and they fail independently. Visitors negotiate with the edge and validate the edge’s certificate; the edge negotiates separately with your origin and validates the origin’s. A migration can leave either one broken while the other is perfect — and the two failures look nothing alike. A broken edge certificate produces an immediate, visible interstitial for everyone. A broken origin certificate produces nothing at all until somebody enables strict origin verification, or until a cache entry expires and the edge has to re-fetch, at which point the site fails everywhere at once for reasons nobody can trace to a change made weeks earlier. This page sits under TLS & Certificate Cutover and covers checking both.
When to Use This Approach
- A CDN, load balancer, or reverse proxy terminates TLS in front of your origin.
- You are moving the origin, the edge provider, or both.
- Non-browser clients — mobile apps, payment gateways, partner integrations — call your hostnames.
- The origin currently uses a self-signed or internal certificate that “works” because verification is disabled.
- You need evidence that the chain is complete rather than the impression that the site loads.
Step-by-Step Instructions
1. Check the Edge Certificate the Way a Strict Client Would
Browsers are the most forgiving client you have: they cache intermediates from other sites and can fetch a missing one on demand, so a chain that is incomplete on the wire still renders a padlock. Count what the server actually sends instead of trusting the padlock.
# Two or more certificates means leaf + intermediate(s); one means an incomplete chain
openssl s_client -connect www.example.com:443 -servername www.example.com \
-showcerts </dev/null 2>/dev/null | grep -c 'BEGIN CERTIFICATE'
Where the count comes back as one, the fix is almost always a configuration pointing at the leaf-only certificate file rather than the full chain. Servers accept either without complaint and serve exactly what they are given, so the defect is invisible in the config and obvious on the wire. Repeat the count after every certificate deployment rather than only the first, because a renewal that writes to a different filename is a common way for a previously correct chain to regress.
2. Check the Origin Certificate Directly, Bypassing the Edge
The edge’s view of your origin is the one that matters for the second connection, and you cannot see it through the public hostname. Connect to the origin’s address with the real SNI, exactly as the edge does, and validate what comes back.
# Talk to the origin as the edge does: real SNI, but pinned to the origin address
openssl s_client -connect 203.0.113.10:443 -servername www.example.com \
</dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
3. Confirm Whether the Edge Is Actually Verifying
A CDN configured to ignore origin certificate errors will happily serve a site whose origin certificate is expired, self-signed, or issued for a different hostname. That is a latent fault, not a working configuration — it fails the moment anyone tightens the setting or the provider changes its default. Check the setting explicitly and, where the origin certificate is not publicly trusted, fix the certificate rather than relaxing the verification.
# Ask the origin whether its chain validates against the public trust store
curl -sI --resolve www.example.com:443:203.0.113.10 https://www.example.com/ >/dev/null \
&& echo "origin chain validates" || echo "origin chain does NOT validate"
Read the SANs, not just the subject. The subject line often shows a single hostname while the certificate legitimately covers several through its subject alternative names, and it is the SAN list the edge matches against. A certificate whose subject looks wrong may be perfectly valid, and one whose subject looks right may still omit the exact name the edge sends — which is the specific failure in the worked example below.
4. Re-check Both After the Record Changes
Everything above is done before cutover against known addresses. Repeat it through the public hostname afterwards, because the path a request takes has changed and the edge may now be reaching a different origin than the one you tested.
# Post-cutover: through the real hostname, following the real path
openssl s_client -connect www.example.com:443 -servername www.example.com \
-showcerts </dev/null 2>/dev/null | grep -E 'subject=|issuer=' | head -4
Worked Example
The sequence below is a CDN adoption rather than an origin move — the case where the second connection is introduced for the first time and therefore has never been tested. A publisher moves its origin behind a new CDN. The edge certificate is provisioned automatically and validates cleanly, so the site loads and everyone signs off. The origin, meanwhile, is still presenting the certificate it had before — issued for the old hostname, and now serving requests for the new one.
Nothing breaks, because the CDN’s default origin setting accepts any certificate. Three weeks later an infrastructure engineer tightens that setting as part of unrelated hardening, and the entire site returns 526 within seconds:
$ curl -sI https://www.example.com/
HTTP/2 526
# Cloudflare 526: invalid SSL certificate presented by the origin
The fix takes four minutes — reissue the origin certificate for the correct hostname — but the diagnosis takes an hour, because nothing in the recent change history mentions certificates and the migration was declared complete weeks earlier. Running the step-2 check at cutover would have surfaced it while the migration was still the obvious suspect.
Record both certificates in the migration inventory alongside their authority, expiry and owner. The edge certificate is frequently provisioned and renewed automatically by the CDN while the origin’s is managed by hand, and the failure mode is assuming one process covers both. Two rows in a table, checked at the same cadence, removes an entire class of surprise nine months later.
Verification
Run both halves before the switch against known addresses, and again afterwards through the public hostname.
# 1. Edge chain is complete (>= 2 certificates)
openssl s_client -connect www.example.com:443 -servername www.example.com \
-showcerts </dev/null 2>/dev/null | grep -c 'BEGIN CERTIFICATE'
# 2. Origin certificate is valid for the hostname the edge will send
openssl s_client -connect 203.0.113.10:443 -servername www.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -ext subjectAltName -dates
# 3. A strict client completes the whole path end to end
curl -sSI https://www.example.com/ | head -1
A clean result is a count of two or more, an origin certificate whose SANs include the hostname the edge sends, and a 200 from a curl that has not been told to skip verification.
FAQ
Does the origin need a publicly trusted certificate, or will an internal one do? An internal one is fine provided the edge is configured to trust that authority specifically, which several providers support through an origin-CA feature. What does not work is an internal certificate with verification switched off — that is not a trust decision, it is the absence of one, and it accepts any certificate including one presented by something that is not your origin. Pick a trusted certificate or an explicitly configured private authority; do not pick neither.
Why does the edge send the public hostname as SNI rather than the origin’s own name?
Because that is how the origin knows which site to serve. The edge is fetching content for www.example.com, so it sends that name, and the origin’s certificate has to cover it — which is why an origin certificate issued for an internal hostname fails even though the internal hostname resolves. Where the origin genuinely needs a different name, most CDNs let you override the SNI and the Host header separately; set both deliberately and certify whichever name you configure.
How does this change if the CDN also caches? It delays the symptom, which makes the origin failure harder to attribute. A cached response continues serving long after the origin has become unreachable, so a broken origin certificate can lie dormant until a cache entry expires or a purge is issued. That is another argument for testing the origin connection directly rather than inferring its health from the fact that the site is up.
Should the origin certificate be renewed on the same schedule as the edge one? Track them separately, because they usually come from different places — the edge certificate is often provisioned and renewed by the CDN automatically, while the origin’s is yours to manage. The failure mode is assuming the automated one covers both. List each certificate, its authority, its expiry and its owner in the same inventory, and alert on the origin’s expiry as loudly as on the edge’s even though its failure is quieter.
Related
← Back to TLS & Certificate Cutover