A certificate expiry rehearsal is not a TLS lesson. It is a dependency-mapping exercise. The useful output is a ranked list of what breaks first in your stack — renewal automation, alerting, trust stores, downstream clients — and a small set of pre-expiry checks you can run this week. The goal is to find the gap between the renewal path you believe you have and the one that actually runs.
Start with renewal paths, not failure modes
Before you can predict what breaks, you need to know which certificates renew automatically, which are manual, and which are imported. Those three categories behave differently under pressure.
Let’s Encrypt has ended its email expiration service. If your only expiry signal was a CA email, you no longer have that signal. That is a concrete example of a renewal path that changed underneath a team without a code change on their side.
For ACME-issued certificates, the renewal path is the ACME client. Certbot’s certificates subcommand lists the certificates Certbot knows about and shows an expiry date, which makes it a reasonable starting inventory for hosts where Certbot is the client. Certificates created with Certbot’s --manual plugin do not support automatic renewal unless combined with an authentication hook script via --manual-auth-hook. That is a renewal path that looks automated in a runbook but is not automated in practice.
AWS Certificate Manager provides managed renewal for Amazon-issued certificates, renewing automatically with DNS validation or sending email notices when expiration approaches. But imported certificates are not eligible for automatic renewal, and certificates issued through ACME certificate automation are not eligible for ACM managed renewal — renewal is managed by the ACME client. ACM certificates are also regional resources, so the same domain in multiple AWS Regions must be renewed independently. Each of those eligibility rules is a place where a team’s mental model can diverge from the actual renewal path.
The four things that usually break first
The retrieved sources do not describe a specific outage sequence, so treat this as a rehearsal checklist rather than a claim about incident frequency. The point is to test each layer against your own stack.
1. Renewal automation that was assumed to be working
The first thing a rehearsal tends to expose is not a TLS handshake failure. It is a renewal path that has not been exercised in months. A cron job that silently fails, a hook script that was never written, a DNS plugin that lost its API token — these are renewal-path failures that only surface at expiry.
Certbot’s --dry-run and --test-cert flags let you test against Let’s Encrypt’s staging environment without consuming production rate limits. Let’s Encrypt recommends testing against staging before using production. The staging environment uses the same rate limits as production but with different values, and its roots are not in browser or client trust stores. Let’s Encrypt explicitly warns that staging roots are not audited or held to the same standards as production roots and are not safe for anything other than testing. That makes staging useful for exercising the renewal path, not for validating trust-store behavior.
2. Alerting
If your only expiry signal is an email from the CA, and that email service has been retired, you have no signal. A rehearsal should include a deliberate test that the alert actually fires and reaches a human. That means checking the alert route, not just the alert rule. An alert that fires into a channel nobody reads is functionally the same as no alert.
For Certbot-managed certificates, certbot certificates gives you an expiry date you can parse. For ACM-managed certificates, the renewal status is visible in the ACM console or API. The rehearsal question is: which of those signals is wired to a human, and when was that route last tested?
3. Trust stores
Trust stores are the layer where staging and production diverge most sharply. Let’s Encrypt’s staging roots are deliberately not in client trust stores. If your rehearsal only tests against staging, you will not exercise the trust-store path that production depends on. RFC 5280 describes an algorithm for X.509 certification path validation, which is the process a client uses to decide whether to trust a presented certificate. A rehearsal that skips the trust-store layer is testing issuance, not validation.
The practical check is to list which trust stores your services depend on — system CA bundles, container base images, language runtimes with bundled roots — and note who owns each. That list is usually shorter than teams expect, and the owners are usually not the same person who owns the certificate.
4. Downstream clients that pin or cache
The retrieved sources do not cover client-side pinning or caching behavior, so this section is a prompt for your own inventory rather than a sourced claim. The rehearsal question is: which clients would not pick up a renewed certificate without a deploy, a restart, or a config change? Those clients are the ones that turn a routine renewal into an incident. If you cannot answer that question from your inventory, the rehearsal has found a gap.
A pre-expiry checklist you can run this week
This is a recommendation, not a sourced procedure. Adjust it to your stack.
- Inventory every certificate and its renewal path. For Certbot hosts, run
certbot certificatesand record the expiry date and certificate name. For ACM, list certificates per region and note which are imported, which are ACME-issued, and which are ACM-managed. For manually issued certificates, note the owner and the last renewal date. - Classify each certificate as automatic, manual, or imported. Automatic means a client renews it without human action. Manual means a human runs a command. Imported means the renewal path is outside the platform’s managed renewal. The classification is the rehearsal’s primary output.
- Exercise one renewal path in staging. Use Certbot’s
--dry-runor--test-certagainst Let’s Encrypt staging. Confirm the challenge completes and the certificate is issued. Do not add staging roots to any trust store you use for ordinary browsing or other activities. - Test the alert route. Trigger the expiry alert deliberately and confirm it reaches a human who knows what to do. If the alert depends on a CA email service, verify that service still exists.
- List trust-store owners. For each service, note which trust store it uses and who owns updates to that trust store. This is the layer staging cannot validate.
- List clients that would not pick up a renewal automatically. Pinned clients, cached certificates, and bundled roots belong here. Note the deploy or restart each one needs.
What to write down afterward
A rehearsal is only useful if it produces a written decision record. The record should name the certificate, the renewal path, the owner, the fallback if renewal fails, and the date the path was last exercised. Without that, the next expiry is a repeat of the same surprise.
The decision record is also where you capture the tradeoff. A manually renewed certificate with a clear owner and a tested fallback is a different risk than a manually renewed certificate with no owner and no fallback. The record makes that difference visible.
If your team is building out recovery procedures more broadly, the same discipline applies to backups and restores. The Recovery Checklist Before You Need It covers that ground for data recovery; certificate renewal is a parallel exercise with a shorter clock.
FAQ
Can I rehearse an expiry in production without causing an outage?
Not by letting a real certificate expire. The safer rehearsal is to exercise the renewal path in staging and to test the alert route in production. Let’s Encrypt’s staging environment exists for the first part; the second part is a matter of triggering your own alerting and confirming delivery.
Does Certbot’s --dry-run test the full renewal path?
It tests the ACME issuance path against staging. It does not test trust-store behavior, because staging roots are not in production trust stores. It also does not test any deploy or reload step that happens after issuance. Treat it as a test of one layer, not the whole path.
Why do ACM imported certificates not renew automatically?
AWS ACM’s managed renewal applies to Amazon-issued certificates. Imported certificates are not eligible, so the renewal path is whatever process imported them. That process needs an owner and a test.
What about ACME certificates issued through ACM?
ACM does not manage renewal for ACME-issued certificates. The ACME client does. If you issue through ACME and expect ACM to renew, you have a gap between the two systems.
How often should we rehearse?
The retrieved sources do not specify a cadence. A reasonable starting point is to exercise each renewal path once per certificate lifetime, and to test the alert route more often. The decision record should note the last exercise date so the cadence is visible.