Guide
CloudFront custom SSL certificate expired
Rotate the ACM certificate in us-east-1 bound to your CloudFront alternate domain names, deploy the distribution update, and confirm the customer hostname—not only the origin load balancer.
Updated May 30, 2026 820 words
cloudfront ssl certificate expired on your alternate domain names breaks the padlock on www and api hostnames viewers resolve—while the default cloudfront.net cert may still look fine in careless tests.
CloudFront terminates TLS at edge PoPs using an ACM certificate in US East (N. Virginia) for custom domains, or the legacy IAM server certificate flow. The origin behind the distribution can hold a separate cert; browsers never see it when you serve only through CloudFront.
Custom SSL incidents spike after ACM validation records disappear during DNS refactors or when teams renew origin ALB certs but not the us-east-1 ACM ARN on the distribution. API and SPA traffic fails uniformly because every viewer hits the same edge configuration.
This guide lists alternate domain names, updates the ACM binding via console or CLI, waits for deployment, and splits edge versus origin checks like CDN edge OK but origin certificate expired when errors persist after edge renewal.
Executive summaries should cite the customer hostname openssl proves and the distribution ID you edited. Finance and marketing rarely know what ACM means, but they understand that www stopped working because the edge cert aged out while a spreadsheet showed green in a different region.
What to check
Record every Alternate domain name (CNAME) on the distribution—marketing often adds SANs in ACM without updating CloudFront. openssl each customer hostname with SNI.
Confirm the ACM certificate ARN in us-east-1 matches the region requirement for CloudFront custom certs. Regional ACM in eu-west-1 cannot attach until re-imported or re-requested in us-east-1.
Read distribution Status; certificate updates need Deployed before global edges present new material. Partial deploys during busy windows still show old notAfter from some PoPs briefly.
If edge TLS recovers but dynamic content fails, test origin TLS directly—origin expiry is a different failure class documented in CDN edge OK but origin certificate expired.
Maintain a runbook column that lists every distribution ID beside its us-east-1 ACM ARN. Teams that manage dozens of microsites lose track of which marketing microsite still uses an imported cert from a deprecated CA. CloudFront invalidations and certificate deploys are independent operations—do not assume a successful invalidation refreshed TLS.
Step-by-step
External confirmation
HOST=www.example.com
echo | openssl s_client -connect "${HOST}:443" -servername "${HOST}" 2>/dev/null \
| openssl x509 -noout -dates -issuer -subject
Locate distribution and cert ARN
aws cloudfront list-distributions --query "DistributionList.Items[?Aliases.Items!=null].[Id,DomainName,Aliases.Items]" --output table
DIST_ID="E1234ABCDEF"
aws cloudfront get-distribution-config --id "$DIST_ID" > /tmp/cf-config.json
Inspect ViewerCertificate in the JSON: AcmCertificateArn, MinimumProtocolVersion, SSLSupportMethod (sni-only vs vip).
Check ACM in us-east-1
aws acm describe-certificate --certificate-arn "$ACM_ARN" --region us-east-1 \
--query 'Certificate.{Status:Status,NotAfter:NotAfter,SubjectAlternativeNames:SubjectAlternativeNames}'
Fix FAILED validation by restoring DNS CNAME tokens ACM issued, then wait for ISSUED status.
Update distribution to new ACM ARN
After ACM reissues (often same logical domain with renewed NotAfter):
python3 <<'PY'
import json, sys
from copy import deepcopy
with open("/tmp/cf-config.json") as f:
data = json.load(f)
cfg = data["DistributionConfig"]
cfg["ViewerCertificate"]["ACMCertificateArn"] = "arn:aws:acm:us-east-1:ACCOUNT:certificate/NEW_ID"
cfg["ViewerCertificate"]["Certificate"] = ""
cfg["ViewerCertificate"]["CertificateSource"] = "acm"
with open("/tmp/cf-updated.json", "w") as f:
json.dump(cfg, f)
print("Wrote /tmp/cf-updated.json")
PY
ETAG=$(python3 -c "import json; print(json.load(open('/tmp/cf-config.json'))['ETag'])")
aws cloudfront update-distribution --id "$DIST_ID" --if-match "$ETAG" \
--distribution-config file:///tmp/cf-updated.json
Console: CloudFront → distribution → General → Edit → Custom SSL certificate → select renewed ACM cert → save. Wait until Last modified shows Deployed.
Distribution deploys can take fifteen to thirty minutes globally. Poll status without hammering updates:
aws cloudfront get-distribution --id "$DIST_ID" --query 'Distribution.Status' --output text
Schedule openssl checks every five minutes from an external host until notAfter advances. Partial propagation can make internal dashboards disagree with customer reports for a short window.
Verify all aliases
for h in www.example.com api.example.com; do
echo "== $h =="
echo | openssl s_client -connect "$h:443" -servername "$h" 2>/dev/null | openssl x509 -noout -dates
done
Origin spot-check (if 502/504 remain)
ORIGIN=origin.example.com
echo | openssl s_client -connect "$ORIGIN:443" -servername "$ORIGIN" 2>/dev/null | openssl x509 -noout -dates
Origin checks use the hostname CloudFront connects to, which may differ from the marketing CNAME. Align with your origin access strategy—custom headers, OAI, or OAC do not change which certificate the origin must present to CloudFront during fetches.
How to read the output
get-distribution-config ViewerCertificate.CertificateSource acm means ARN swaps drive renewal. cloudfront_default_certificate means you are not on custom SSL—users hitting CNAMEs may mismatch.
CloudFront deployment spinner in console correlates with edge propagation; openssl from multiple regions reduces false “still expired” reports during rollout.
When MinimumProtocolVersion is TLSv1.2_2019 or newer, legacy clients may fail for protocol reasons unrelated to expiry—do not confuse with date errors.
ACM sends EventBridge notifications when certificates approach expiry if you enabled them—wire those events to the same channel that receives cloudfront ssl certificate expired pages so distribution owners cannot ignore us-east-1 renewal debt.
If you use Terraform, bump the viewer certificate ARN in state and apply with the same ETag discipline as CLI—drift detection should compare live openssl notAfter to ACM describe output weekly, not only at expiry.
Common mistakes
Renewing ALB certs in the workload region but forgetting us-east-1 ACM used by CloudFront.
Removing validation CNAMEs when cleaning Route 53, silently blocking ACM auto-renew.
Attaching a cert whose SAN list omits a newly marketed subdomain added only to CloudFront aliases.
Purging cache believing it fixes TLS—it does not; cert binding changes require distribution update and deploy.
Testing the xyz.cloudfront.net domain when executives bookmark the branded CNAME.
Stopping after edge fix while origin cert expired—see load balancer presenting an expired certificate on the origin ALB.
Editing distribution JSON by hand without preserving required fields like Origins and CacheBehaviors—always start from get-distribution-config and modify ViewerCertificate only unless you intend a broader change.
Using the wrong AWS account CLI profile while ACM in us-east-1 shows ISSUED—openssl still reads expired material from the account that actually serves traffic.
When to use automation
Distributions and SAN sprawl exceed spreadsheet tracking. Monitor each customer-facing CNAME with live TLS checks, not only ACM console NotAfter columns that ignore attachment drift.
ssldays reads issuer, SANs, chain trust, and expiry from the internet and alerts at 30, 14, 7, and 1 days. RDAP helps when domain validation needs healthy registrar data. Email on all tiers; Slack and Discord webhooks on Starter and Pro.
Use /check after deploy completes, then /register for every alias on the distribution. Pair with AWS ALB listener certificate expired when CloudFront origins are regional ALBs.
Frequently asked questions
Does ACM renewal update CloudFront automatically?
In-place ACM renewal for the same ARN often propagates without distribution edits, but describe-certificate and external openssl should prove it. New ARNs always need a distribution update.
What about imported certs?
Imported ACM certs do not auto-renew; you must import a replacement and update the distribution binding before notAfter.
IPv6 viewers?
Same certificate applies; test AAAA records if customers report mobile-only failures.
Legacy SNI-only requirement?
Modern distributions use SNI-only custom certs without dedicated IP fees; vip-style legacy setups are rare but still expire on their bound cert.
Monitor this hostname on a schedule
Live certificate checks and renewal reminders — not guesswork from PEM files.