The TLS handshake failed because a server presented a certificate that the client no longer considered valid due to its expiration date.
This most commonly happens because the certificate on the server has genuinely expired and needs to be renewed. The server’s TLS/SSL configuration might be pointing to an old, expired certificate file instead of the newly generated one. If you’re using a certificate management system (like cert-manager in Kubernetes or a cloud provider’s certificate service), that system might have failed to automatically renew the certificate, or the renewal process itself encountered an error. Network intermediaries, such as load balancers or reverse proxies, might be caching an expired certificate and presenting it to clients even if the backend server has a valid, renewed certificate. The system’s clock on either the client or server might be significantly out of sync, leading to a misinterpretation of the certificate’s validity period. Finally, the certificate was correctly renewed, but the web server or application service was not restarted or reloaded to pick up the new certificate.
Diagnosis and Fixes:
-
Server Certificate Expiration:
- Diagnosis: On the server, check the certificate file’s expiration date. For OpenSSL, use:
If the output shows a date in the past, the certificate has expired.openssl x509 -in /path/to/your/certificate.crt -noout -enddate - Fix: Obtain a new certificate from your Certificate Authority (CA) and replace the expired file on the server. Then, configure your web server (e.g., Nginx, Apache) or application to use the new certificate. For Nginx, this would involve updating the
ssl_certificateandssl_certificate_keydirectives in yournginx.confor site-specific configuration file, followed by a reload:# Example Nginx configuration snippet ssl_certificate /etc/ssl/certs/your_new_domain.crt; ssl_certificate_key /etc/ssl/private/your_new_domain.key;sudo systemctl reload nginx - Why it works: This directly replaces the invalid certificate with a valid, current one, satisfying the TLS handshake requirement.
- Diagnosis: On the server, check the certificate file’s expiration date. For OpenSSL, use:
-
Incorrect Certificate File Path:
- Diagnosis: Review your web server or application’s TLS/SSL configuration to ensure the paths to the certificate and private key files are correct and point to the newly renewed files, not old ones.
- Fix: Edit the configuration file to correct the file paths. For example, in Apache’s
ssl.confor virtual host configuration:
Then reload the service:SSLCertificateFile /etc/ssl/certs/your_new_domain.crt SSLCertificateKeyFile /etc/ssl/private/your_new_domain.keysudo systemctl reload apache2 - Why it works: The server was likely configured to use the correct name for the new certificate, but the actual file at that location was still the old, expired one. Correcting the path or ensuring the new file is at the expected location resolves this.
-
Certificate Renewal System Failure:
- Diagnosis: If using an automated system like cert-manager in Kubernetes, check its logs for errors related to certificate issuance or renewal. For example, in Kubernetes:
Also, check the status of thekubectl logs -n cert-manager <cert-manager-pod-name>Certificateresource:
Look for events indicating failure to obtain or renew.kubectl describe certificate <your-certificate-name> -n <your-namespace> - Fix: Address the specific error indicated in the logs. This might involve fixing DNS challenges (e.g., ensuring
_acme-challengeTXT records are correctly propagated), resolving API rate limits with the CA, or ensuring theIssuerorClusterIssueris correctly configured. For a DNS challenge issue, you might need to update your DNS provider’s configuration. - Why it works: Automated renewal systems fail for specific reasons. Diagnosing and fixing the root cause (DNS, API, configuration) allows the system to successfully obtain a new certificate.
- Diagnosis: If using an automated system like cert-manager in Kubernetes, check its logs for errors related to certificate issuance or renewal. For example, in Kubernetes:
-
Proxy/Load Balancer Caching:
- Diagnosis: If a load balancer or reverse proxy sits in front of your application server, it might be terminating TLS and presenting its own certificate. Check the certificate presented by the proxy, not just the backend server. You can use
openssl s_clientpointed at the proxy’s IP/hostname:
Examine the certificate details in the output.openssl s_client -connect your.proxy.domain.com:443 -servername your.proxy.domain.com - Fix: Renew or update the certificate on the proxy/load balancer. If it’s a managed service (e.g., AWS ELB, GCP Load Balancer), update the certificate associated with the listener. If it’s a self-hosted proxy like HAProxy or Traefik, update its configuration and reload it.
# Example for updating an AWS ACM certificate on an ELB # This is done via the AWS Console or AWS CLI, not a direct command. # Ensure the ARN of the renewed certificate is associated with the HTTPS listener. - Why it works: Proxies often cache TLS connections and presented certificates. Updating the certificate on the proxy ensures it presents a valid certificate to clients.
- Diagnosis: If a load balancer or reverse proxy sits in front of your application server, it might be terminating TLS and presenting its own certificate. Check the certificate presented by the proxy, not just the backend server. You can use
-
System Clock Skew:
- Diagnosis: Check the current date and time on both the client machine attempting to connect and the server machine hosting the certificate.
If the time is off by more than a few minutes (or longer, depending on the CA’s tolerance), it can cause expiration issues.date - Fix: Synchronize the system clocks using NTP. On Linux servers:
Ensure clients also have their clocks synchronized.sudo apt update && sudo apt install ntp sudo systemctl enable ntp sudo systemctl start ntp # Or for systemd-timesyncd: sudo timedatectl set-ntp true - Why it works: TLS certificate validation relies on accurate timestamps. Synchronizing clocks ensures the server’s certificate is evaluated against the correct current time.
- Diagnosis: Check the current date and time on both the client machine attempting to connect and the server machine hosting the certificate.
-
Service Not Reloaded After Update:
- Diagnosis: Even if the certificate file is updated and the configuration points to it, the web server process might still be running with the old certificate loaded in memory. This is often indicated by the certificate appearing valid in file system checks but still expiring in browser/client checks.
- Fix: Perform a graceful reload or restart of the web server or application service.
# For Nginx sudo systemctl reload nginx # For Apache sudo systemctl reload apache2 # For systemd services in general sudo systemctl restart your-service-name.service - Why it works: Reloading the service forces it to re-read its configuration and load the new certificate from disk into memory, replacing the old, expired one.
The next error you’ll likely encounter if you fix this is a TLS Alert unknown_ca if the new certificate was issued by an intermediate CA that your clients don’t trust, or if the certificate chain is incomplete.