When a certificate expires, every client that validates it stops connecting at the same moment, and the hardest part of the outage is usually working out which certificate expired, where copies of it are served and why the renewed one is not being used. The expired certificate is not always the website's leaf: it may be an intermediate, a cross-signed root, a client certificate used for mTLS, a Kubernetes control plane certificate or a certificate inside an appliance. This guide is a troubleshooting and recovery reference for the outage itself: how the failure shows up in each client, how to find the expired link quickly, how to restore service without new mistakes, and what to fix afterwards. It is for SRE, platform and security engineers on call. Prevention, automation and the CA/Browser Forum move to 47-day certificates are covered in the Certificate Expiry Outages and 47-Day TLS Certificates Guide, which this page does not repeat. Error strings were checked against Go, OpenSSL, Node.js, Chromium and Kubernetes sources on 11 November 2026.
Key takeaways
- Identify the expired link before renewing anything. Check every certificate in the served chain and any client certificate; renewing the leaf does nothing if an intermediate or root has expired.
- Check the clock as well as the certificate. OpenSSL's own message for a not-yet-valid certificate says "or the system clock is incorrect", and a device with a wrong date sees valid certificates as expired.
- Renewed is not deployed, and deployed is not loaded. Most extended outages come from a new certificate that exists in a vault or on disk while the listener still serves the old one from memory or from another copy.
- Restore with the same identity, not a weaker one. Do not swap in a self-signed certificate or disable verification on clients to buy time; that creates a second incident.
- Every outage is an inventory failure. After recovery, record where the certificate lived, who owned it and why the warning was missed, then fix that path.
How an expiry outage shows up
Symptoms appear on the client side, often far from the team that owns the certificate. The messages below are exact strings from each stack's source or documentation.
| Client | Message or code | Notes |
|---|---|---|
| Go (kubectl, Docker, Terraform, Prometheus) | x509: certificate has expired or is not yet valid: followed by the current time and the expiry time | The detail shows both times, which immediately reveals clock skew |
| OpenSSL and curl (code 10) | certificate has expired; curl prefixes SSL certificate problem: | curl exits with code 60 |
| OpenSSL (code 9) | certificate is not yet valid or the system clock is incorrect | Usually a client clock or a certificate issued with a future start time |
| Node.js | CERT_HAS_EXPIRED | Also CERT_NOT_YET_VALID |
Python ssl | SSLCertVerificationError, reason CERTIFICATE_VERIFY_FAILED | verify_message contains the OpenSSL text |
| Java (JSSE) | PKIX path validation failed: followed by the cause | The cause names the validity check that failed |
| Chromium browsers | ERR_CERT_DATE_INVALID (net error -201) | Shown as NET::ERR_CERT_DATE_INVALID on the interstitial |
| TLS peer receiving an alert | certificate_expired (alert 45); Go reports remote error: tls: expired certificate | The other side rejected your certificate: look at client certificates in mTLS |
The last row matters. If a server logs that its client rejected the connection with alert 45, or a client receives that alert, the expired certificate is the one the receiving side presented, which in mTLS is often a client or workload certificate rather than the server's.
Likely causes, most to least common
- Leaf expired and nobody renewed it: a manually managed certificate with no owner or a dead notification address.
- Renewed but not deployed everywhere: the new certificate reached one host, but a load balancer, CDN, API gateway, Java keystore or appliance still holds the old copy.
- Deployed but not reloaded: the file changed on disk, but the server process has the old certificate in memory. Web servers, proxies and many Java applications need a reload or restart.
- Client or workload certificate expired: mTLS client certificates, service mesh workload certificates, VPN machine certificates and agent certificates often have no monitoring at all. See the mTLS Guide.
- Intermediate or root expired: the leaf is valid but something above it is not, or clients only trust an old root. When Let's Encrypt's DST Root CA X3 cross-sign expired on 30 September 2021, older clients that did not trust ISRG Root X1 failed, and Let's Encrypt warned that OpenSSL 1.0.x clients would fail even when they trusted ISRG Root X1.
- Platform certificates with their own lifetime: kubeadm documents that client certificates it generates "expire after 1 year", and that it renews them during control plane upgrades. A cluster not upgraded for a year loses API server access.
- Clock skew: a host or device with a wrong date (dead RTC battery, NTP blocked, a VM restored from a snapshot) sees valid certificates as expired or not yet valid.
- Stale OCSP stapled response or CRL: a stapled response or CRL past its next update can cause strict clients to fail; see the Certificate Revocation Guide.
Triage in the first fifteen minutes
- Confirm it is expiry: read the full error from a failing client. A date error is expiry or clock; "unknown authority" or a name mismatch is a different problem (see the x509 Certificate Signed by Unknown Authority Troubleshooting Guide).
- Look at what is actually served: run
openssl s_client -connect host:443 -servername host -showcertsand, for each certificate block,openssl x509 -noout -subject -issuer -enddate. Note which certificate'snotAfteris in the past. - Check from more than one path: query each load balancer node, region, CDN edge and the origin directly. Mixed results mean partial deployment, which changes the fix from "renew" to "redeploy".
- Check the clock on a failing client: compare the failing system's time with a trusted source. Go's error message prints both times for this reason.
- For mTLS, check both directions: inspect the client certificate the caller presents (keystore, secret, mounted file) as well as the server's.
- Use time travel to test:
openssl verify -attime <epoch>validates a chain at a given time, which helps confirm whether a replacement chain will still be valid tomorrow, and whether a not-yet-valid start date is the problem. - Declare scope: list every hostname, SAN and system that uses the same certificate or key. A wildcard or multi-SAN certificate usually breaks many services at once.
Where certificates hide: a locator table
| Location | How to read the expiry | What has to happen after renewal |
|---|---|---|
| Web server or reverse proxy on a host | openssl x509 -noout -enddate -in <file> | Replace file, reload the service |
| Kubernetes Secret used by an ingress | Decode the tls.crt field and read it with openssl x509 | Ingress controller must pick up the new Secret |
cert-manager Certificate | status.notAfter, status.renewalTime and the Ready condition | Check the CertificateRequest and issuer if renewal failed |
| kubeadm control plane | kubeadm certs check-expiration | kubeadm certs renew all, then restart control plane components and update admin kubeconfig |
| Java keystore or truststore | keytool -list -v -keystore <file> | Import, then restart the JVM |
| AWS Certificate Manager | CloudWatch metric DaysToExpiry per CertificateArn | Imported certificates are not renewed by ACM; reimport |
| Windows certificate store | Certificates MMC or certutil -store My | Rebind in IIS or the consuming service |
| Appliances, firmware, SaaS SSO configurations | Vendor console or metadata | Vendor-specific upload; often a manual step |
For the kubeadm row, the Kubernetes documentation states that kubeadm certs check-expiration shows expiry for client certificates in /etc/kubernetes/pki and the certificates embedded in kubeconfig files, and that the default CA validity is ten years while leaf certificates are one year. For cert-manager, the default renewal point is two-thirds of the way through the certificate's duration unless renewBefore or renewBeforePercentage is set.
Restoring service safely
- Get a valid certificate for the same names: trigger renewal through the normal path (ACME client, cert-manager, internal CA, ACM) if it is healthy. If the automated path is broken, issue manually from the same CA, keeping the same SANs and key type so clients see no other change. The Certificate Renewal Runbook Template gives a ready sequence.
- Build the correct chain: serve the leaf plus current intermediates. If the expiry was an intermediate or cross-sign, take the CA's current chain rather than reusing the old bundle file.
- Deploy to every copy found during triage: work from the locator table, not from memory. Record each location as you go; that list becomes the inventory entry.
- Reload and verify each endpoint: after reload, re-run
s_clientagainst every node and edge and confirm the newnotAfter. Do not trust the deployment tool's success message alone. - Clear client-side state: clients with pinned certificates, cached sessions or a copied certificate in their own truststore may need an update. Pinned clients cannot recover without a release if the pin was to the leaf key; see the Certificate Pinning guide.
- Roll back path: keep the expired certificate and key archived (not deleted) until the new one is confirmed everywhere, so a failed deployment can be compared, but never redeploy an expired certificate as a fix.
Clock problems: fix time synchronisation, not the certificate. For fleets of devices that cannot keep time, the long-term fix is reliable NTP or a time source in the device design.
Do not: install a self-signed certificate, tell users to click through warnings, or set verification bypasses on clients. Each of these teaches users and services to accept interception and tends to outlive the outage.
Decision guidance
- Single public endpoint, ACME available: renew through ACME and fix the automation fault afterwards. See the ACME and Automated Certificate Management Guide.
- Internal CA certificate: issue from the internal CA with the same profile; if the internal CA's own certificate has expired, every certificate it signed is affected and this becomes a CA replacement exercise. See the CA Compromise and Mass Certificate Replacement Playbook.
- Root or cross-sign expiry hitting old clients: serve a chain those clients can validate if the CA offers one, and plan client trust store updates; you cannot renew a root for someone else.
- Small organisation: a shared on-call note listing every certificate location and its renewal method is the minimum; most small-team outages are a forgotten manual certificate.
- Large organisation: route the incident through the certificate owner registry; if there is no owner, assign one before closing the incident.
Where identity fits
A certificate is a machine identity, and expiry is that identity's credential lapsing. The same failure appears with other non-human credentials: an expired client secret on an app registration, an expired signing certificate on a SAML or token issuer, or a rotated key not loaded by a consumer. Teams that already track certificates as identities with owners and lifecycles recover faster. See the Machine Identity, PKI and Certificate Lifecycle Guide, How to find expiring app secrets and certificates in Entra ID and the Secret Rotation Outage Troubleshooting Guide.
Detection and measurement
- External probes: check the served certificate chain on every hostname and every node, alerting on the earliest
notAfterin the chain, not only the leaf. - Platform signals: ACM
DaysToExpiry, cert-manager Ready condition and renewal time,kubeadm certs check-expirationon a schedule, keystore scans. - Client error telemetry: alert on spikes of
CERT_HAS_EXPIRED,certificate has expiredor alert 45 in client and proxy logs; this catches certificates nobody inventoried. - Metrics: expiry incidents per quarter (target zero); minimum days to expiry across the estate; percentage of certificates with automated renewal and a named owner; time from detection to restored service; renewals that succeeded but were not deployed within 24 hours.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev. 5 | SC-12 Cryptographic Key Establishment and Management; SC-17 Public Key Infrastructure Certificates; CM-8 System Component Inventory; SI-4 System Monitoring | Certificate lifecycle, inventory of where certificates live, monitoring of expiry |
| NIST CSF 2.0 | ID.AM-08; DE.CM-09; RC.RP-01 | Life cycle management, monitoring of runtime environments, executing recovery |
| CIS Controls v8.1 | 3.10 Encrypt Sensitive Data in Transit | Valid certificates are a precondition for encrypted transport |
| ISO/IEC 27001:2022 Annex A | A.8.24 Use of cryptography; A.5.9 Inventory of information and other associated assets | Key and certificate management rules, inventory |
| MITRE D3FEND | D3-CA Certificate Analysis | Analysing certificate validity as a monitoring control |
Common failure patterns
- Renewing the leaf when the intermediate expired: the new leaf is chained to the same expired intermediate bundle file and the outage continues.
- Fixing one node: one load balancer member or region keeps the old certificate, producing intermittent failures that look like a network problem.
- Forgotten reload: automation writes the file but the process keeps the old certificate until the next unrelated restart, sometimes weeks later.
- Ignoring client certificates: mTLS client and agent certificates expire silently and the server team spends hours on its own, valid, certificate.
- Annual platform certificates: Kubernetes clusters that are not upgraded within a year lose control plane access when kubeadm-issued certificates expire.
- Clicking through: users told to accept a warning during an outage keep doing it, which helps any later interception attempt.
Practitioner checklist
- Read the exact client error and confirm it is a date failure, not trust or name.
- Check
notAfterfor every certificate in the served chain and any client certificate. - Check the clock on a failing client before changing certificates.
- Probe every node, region and edge to find all copies.
- Renew through the normal path with the same names and key type, and rebuild the chain from the CA's current intermediates.
- Deploy to every location, reload, and verify the new expiry on each endpoint.
- Never deploy self-signed replacements or client verification bypasses as a stopgap.
- After recovery, record each location in the inventory, assign an owner and fix the warning path that failed.
Standards and references
- IETF: RFC 8446 The Transport Layer Security (TLS) Protocol Version 1.3
- Kubernetes: Certificate Management with kubeadm
- cert-manager: Certificate resource
- AWS: Supported CloudWatch metrics for ACM
- Let's Encrypt: DST Root CA X3 Expiration (September 2021)
- OpenSSL: openssl-verification-options
- Node.js: TLS (SSL) documentation
- MITRE D3FEND: Certificate Analysis
Related NHI Mgmt Group resources: Certificate Expiry Outages and 47-Day TLS Certificates Guide · Certificate Renewal Runbook Template · Certificate Inventory Register Template · TLS Handshake Failure Troubleshooting Guide