SSL Certificate Verification Failed errors are one of the most common and frustrating issues for developers, DevOps engineers, and system administrators. Whether you're building a Python application, running a Docker container, or managing a web server, this guide will help you:
- Identify the exact cause of the SSL error
- Fix it step-by-step with proven solutions
- Prevent it from happening again with the best practice
Table of Contents:
What Does "SSL Certificate Verification Failed" Mean?
Common Causes of SSL Certificate Verification Failures
Advanced / Rare Causes of SSL Certificate Verification Failures
Python-Specific SSL Troubleshooting
How to Detect SSL Certificate Problems
Best Practices to Prevent SSL Errors
Conclusion
FAQ
What Does "SSL Certificate Verification Failed" Mean?
This error occurs when your application or browser cannot verify the identity of the server it's connecting to. The trust chain between your client and the server's SSL/TLS certificate is broken, meaning there's a problem with the certificate, the server configuration, or your environment.
What are the Common Causes of SSL Certificate Verification Failures?
1. Outdated or Missing Root Certificates
SSL verification relies on a list of trusted root Certificate Authorities (CAs) stored on your system or within your application. If this list is outdated or missing the CA that issued the server's certificate, the trust chain breaks, and the connection is rejected, even if the server's certificate is valid.
Solution: Update your system's CA bundle or your application's certificate store to include the latest trusted root certificates. On most operating systems, this means running a system update. In Python, update the certifi
package with:
pip install --upgrade certifi
Ensure your application is using the correct, updated CA file when verifying SSL connections.
2. Hostname Mismatch
When connecting over HTTPS, the server's SSL certificate must match the exact domain name (hostname) you're requesting. If the Common Name (CN) or Subject Alternative Name (SAN) in the certificate does not match the hostname in the URL, the SSL verification fails. For example, if the certificate is for www.example.com but you access api.example.com, the names do not match, and the connection is rejected.
Solution: Verify that the domain in your request exactly matches one of the names listed in the certificate's CN or SAN fields. If there's a mismatch, either:
- Access the correct hostname that the certificate covers, or
- Reissue the SSL certificate to include the intended hostname(s) in the SAN list.
You can inspect the certificate using:
openssl s_client -connect example.com:443 -servername example.com
and reviewing the CN and SAN values.
3. Expired Certificate
Every SSL/TLS certificate has a defined validity period with a start date and an expiration date. If the current date is beyond the expiration date, the certificate is considered invalid, and SSL verification will fail. Expired certificates can no longer guarantee secure communication because they may indicate that the server is not being actively maintained or renewed.
Solution: Check the certificate's expiration date using:
openssl x509 -in cert.pem -noout –enddate
or by viewing it in your browser's certificate details. If it's expired, renew it through your Certificate Authority (CA) or automate the process with tools like WebSitePulse's SSL / TLS Certificate Monitoring to prevent future downtime. Always plan renewals before the expiry date to avoid service interruptions.
4. Not Yet Valid Certificate
An SSL/TLS certificate has a start date ("Not Before") that marks when it becomes valid. If the current date is before this start date, the certificate is considered "not yet valid," and SSL verification will fail. This can happen if the certificate was issued for a future activation date or if the server or client system clock is set incorrectly.
Solution: Check the certificate's start date using:
openssl x509 -in cert.pem -noout –startdate
If the date is in the future, either wait until it becomes valid or reissue the certificate with the correct validity period. Also, verify and correct the system clock and timezone on both client and server to ensure accurate time synchronization.
5. Revoked Certificate
An SSL/TLS certificate can be revoked by its issuing Certificate Authority (CA) before its expiration date. Revocation usually occurs if the private key is compromised, the domain ownership changes, or the certificate was issued in error. When a client checks the certificate status via CRL (Certificate Revocation List) or OCSP (Online Certificate Status Protocol) and finds it revoked, SSL verification fails.
Solution: Confirm revocation status using:
openssl verify -crl_check -CAfile ca-bundle.crt cert.pem
or an OCSP check with:
openssl ocsp -issuer issuer.pem -cert cert.pem -url http://ocsp.example.com
If revoked, the only solution is to obtain and install a new, valid certificate from the CA. Also, investigate and address the reason for revocation to prevent recurrence.
6. Intermediate Certificate Missing
SSL/TLS certificates are usually issued in a chain: the server certificate → one or more intermediate certificates → a trusted root certificate. If the server does not send the required intermediate certificate(s) during the handshake, the client cannot complete the trust chain, even if the root is trusted. This results in an SSL verification failure, often labeled as an "incomplete chain" or "unable to get local issuer certificate."
Solution: Check the certificate chain using:
openssl s_client -connect example.com:443 –showcerts
If intermediates are missing, configure your server to send the full certificate chain file (server certificate + intermediate(s) + root if required). Certificate Authorities usually provide this as a "bundle" or "fullchain" file. After updating the server configuration, restart the web server and retest the chain.
7. Using Deprecated TLS Versions
TLS (Transport Layer Security) is the protocol that secures HTTPS connections. Older versions like TLS 1.0 and TLS 1.1 are now deprecated due to known vulnerabilities. Many modern browsers, APIs, and SSL libraries refuse to connect using these outdated versions. If a server only supports deprecated TLS versions, or if a client is too old to support TLS 1.2 or TLS 1.3, the SSL handshake will fail.
Solution: Check supported TLS versions on the server with:
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
If the server does not support TLS 1.2/1.3, update its configuration to enable modern versions. For clients, update the operating system, SSL libraries (like OpenSSL), and any relevant software to ensure compatibility with TLS 1.2 or higher. Disabling old TLS versions is a security best practice.
8. Deprecated Algorithms
SSL/TLS certificates are signed using cryptographic algorithms (e.g., SHA-256, RSA). Older algorithms like SHA-1 or weak RSA keys (<2048 bits="" are="" considered="" insecure="" because="" they="" can="" be="" exploited="" with="" modern="" computing="" power="" many="" browsers="" apis="" and="" ssl="" libraries="" now="" reject="" certificates="" using="" deprecated="" algorithms="" causing="" verification="" to="" fail="" --2048--="">
Solution: Check the algorithm with:
openssl x509 -in cert.pem -text | grep "Signature Algorithm"
If it shows SHA-1 or a weak key size, reissue the certificate using a modern algorithm such as SHA-256 (or stronger) and RSA 2048-bit or ECDSA keys. Always follow current CA/B Forum security guidelines to ensure long-term compatibility.
9. Wrong Key Usage / EKU
Every SSL/TLS certificate contains fields for Key Usage and Extended Key Usage (EKU) that define how the certificate can be used. For example, a web server certificate must have the EKU TLS Web Server Authentication
. If these fields are missing or incorrectly set (e.g., a client authentication certificate used for a server), SSL verification will fail because the certificate's purpose does not match the intended connection type.
Solution: Inspect the certificate's usage fields with:
openssl x509 -in cert.pem -text | grep -A1 "Key Usage"
openssl x509 -in cert.pem -text | grep -A1 "Extended Key Usage"
If the usage values are incorrect, reissue the certificate from your Certificate Authority (CA) with the proper Key Usage and EKU settings for its role (e.g., Server Authentication for websites, Client Authentication for API clients). This ensures the certificate is valid for the intended operation.
10. Self-Signed Certificate
A self-signed certificate is one that is issued and signed by the same entity, rather than by a trusted public Certificate Authority (CA). Because it is not linked to a trusted root CA in the client's certificate store, the trust chain cannot be verified, and SSL verification will fail by default. This is common in development environments, internal networks, or when testing services.
Solution: Check if the certificate is self-signed with:
openssl x509 -in cert.pem -noout -issuer –subject
If the issuer and subject are identical, it is self-signed.
To resolve this:
- For public-facing services: replace it with a certificate from a trusted CA.
- For internal or testing environments: manually add the self-signed certificate to the client's trusted certificate store so it's recognized as valid.
Advanced / Rare Causes of SSL Certificate Verification Failures
11. Clock Skew / Timezone Issues
SSL/TLS certificates are only valid within a specific date range. If the client or server system clock is incorrect, either ahead, behind, or in the wrong timezone, the certificate may appear expired or not yet valid even if it's actually fine. This is known as clock skew, and it can cause SSL verification to fail during the handshake.
Solution: Check the system date and time with:
date
Compare it to a reliable time source (e.g., an NTP server). If it's wrong, correct the date, time, and timezone settings, and enable automatic time synchronization (NTP). On Linux, use:
sudo timedatectl set-ntp true
On Windows, enable "Set time automatically" in the Date & Time settings. This ensures accurate certificate validity checks.
12. SNI Issues
Server Name Indication (SNI) is an extension to the TLS protocol that allows a client to tell the server which hostname it is trying to connect to during the SSL handshake. This is essential when multiple domains are hosted on the same IP address. If the client does not send the correct SNI, or the server is misconfigured and returns the wrong certificate for that hostname, SSL verification will fail due to a hostname mismatch. Older clients or outdated SSL libraries may also lack SNI support.
Solution: Test the connection with SNI explicitly set:
openssl s_client -connect example.com:443 -servername example.com
If the returned certificate does not match the hostname, update the server configuration to serve the correct certificate for that domain. For clients, ensure you are using an SNI-capable library (modern versions of OpenSSL, Python, curl, etc.). In cases where SNI is missing in requests, explicitly set the server name in your connection settings or upgrade the client software to support SNI.
13. Cross-Signed Root Confusion
Some SSL/TLS certificates are cross-signed, meaning they can be validated by more than one root Certificate Authority (CA). While this can improve compatibility, it can also cause root selection conflicts. If a client chooses a root certificate that is not present in its trust store or one that has expired, the trust chain breaks, leading to SSL verification failure. This is often seen when servers send an unexpected or non-optimal certificate chain.
Solution: Check the provided certificate chain using:
openssl s_client -connect example.com:443 –showcerts
If the server is sending a problematic chain, update its configuration to serve the preferred certificate chain that matches the most widely trusted and current root CA. Many Certificate Authorities provide multiple chain options — choose the one best suited for modern clients.
14. Wrong Trust Store in Use
An SSL/TLS client verifies certificates against a trust store — a collection of trusted root Certificate Authorities (CAs). If the application is configured to use the wrong trust store or a trust store missing the required root certificate, verification will fail even if the server's certificate is valid. This issue often occurs in custom application setups, Docker containers, Python virtual environments, or when environment variables point to an outdated or incorrect CA bundle.
Solution: Determine which trust store the application is using:
- Python:
import certifi
print(certifi.where())
- cURL / Requests: Check the
REQUESTS_CA_BUNDLE
orCURL_CA_BUNDLE
environment variables.
If the trust store is incorrect or outdated:
• Update it with the latest root CAs (e.g., apt install --reinstall ca-certificates
on Linux, pip install --upgrade certifi
for Python).
• Ensure environment variables point to the correct CA bundle.
• In containerized environments, install and maintain ca-certificates
inside the image.
15. Proxy / Firewall SSL Interception
Some corporate networks, ISPs, or security appliances (like firewalls and web gateways) perform SSL interception to inspect encrypted traffic. They act as a "man-in-the-middle" by presenting their own certificate to the client, then establishing a separate encrypted connection to the server. If the client's trust store does not trust the proxy or firewall's root certificate, SSL verification will fail.
Solution: Check the certificate issuer when connected through the network:
openssl s_client -connect example.com:443 -servername example.com
If the issuer is the proxy/firewall rather than a public Certificate Authority, you have SSL interception. To fix this:
- Add the proxy/firewall's root certificate to the client's trust store (common in corporate environments).
- Alternatively, configure the application to bypass SSL inspection for specific domains if the policy allows.
- For public services, connect through a network that does not intercept SSL traffic.
16. Antivirus MITM
Some antivirus or endpoint security software inspects HTTPS traffic by acting as a local man-in-the-middle (MITM). It installs its own root certificate, intercepts encrypted connections, decrypts them for scanning, then re-encrypts them before sending to the browser or application. If the application or system does not trust the antivirus's root certificate, SSL verification will fail. This is common with HTTPS-scanning features in consumer security tools.
Solution: Check the certificate issuer when accessing a site:
openssl s_client -connect example.com:443 -servername example.com
If the issuer is the antivirus vendor instead of a public Certificate Authority, HTTPS scanning is active. To fix this:
- Option 1: Import the antivirus root certificate into the system or application trust store.
- Option 2: Disable HTTPS scanning in the antivirus settings (safer for avoiding MITM issues).
- Option 3: Use a trusted network path without interception for critical communications.
17. Load Balancer / CDN Misconfiguration
When using a load balancer or Content Delivery Network (CDN), the SSL/TLS certificate presented to clients may be managed at the edge rather than on the origin server. If the load balancer or CDN is misconfigured, for example, serving the wrong certificate, an incomplete chain, or a certificate for a different domain, SSL verification will fail. This can happen if the certificate wasn't uploaded correctly, expired at the edge, or the wrong domain mapping was applied.
Solution: Test the SSL connection directly against both the CDN/load balancer endpoint and the origin server:
openssl s_client -connect cdn.example.com:443 -servername cdn.example.com
openssl s_client -connect origin.example.com:443 -servername origin.example.com
If the certificate differs or is invalid on the CDN/load balancer, update its configuration:
- Upload the correct, full certificate chain.
- Ensure the mapped domain matches the certificate's CN/SAN.
- Renew or replace expired certificates at the edge.
- If using automated certificate provisioning (e.g., Let's Encrypt), confirm the process runs on the CDN/load balancer as well as the origin.
18. Docker / Container Missing Cas
Docker images and other containerized environments often start with minimal operating system packages to reduce size. These stripped-down images may lack the default set of trusted root Certificate Authorities (CAs) in /etc/ssl/certs
or their equivalent. Without these CAs, the container cannot verify SSL/TLS certificates, causing HTTPS requests and API calls to fail, even if the certificates are valid.
Solution: Check if CA certificates are installed inside the container:
ls /etc/ssl/certs
If the directory is empty or missing expected files, install the CA bundle package:
- Debian/Ubuntu:
apt-get update && apt-get install -y ca-certificates
update-ca-certificates
- Alpine:
apk add --no-cache ca-certificates
update-ca-certificates
- CentOS/RHEL:
yum install -y ca-certificates
update-ca-trust force-enable
Rebuild the container with CA installation steps in the Dockerfile to ensure future images include trusted root certificates.
19. Certificate Transparency (CT) Issues
Certificate Transparency (CT) is a security standard requiring SSL/TLS certificates issued by public Certificate Authorities to be logged in publicly auditable CT logs. Modern browsers, like Chrome, enforce CT compliance. If a certificate is not present in CT logs, for example, due to misconfiguration by the Certificate Authority or using a private/internal CA, browsers and some clients may reject it, resulting in SSL verification failures.
Solution: Check CT status using tools like SSL Labs Test. If the certificate is missing from CT logs:
- Contact the Certificate Authority to reissue a CT-compliant certificate.
- For internal/private services where CT is not applicable, configure clients or browsers to allow the certificate (not recommended for public-facing services).
- When ordering a certificate, ensure CT logging is enabled in the request or by default from the CA.
20. Mixed IPv4/IPv6 DNS Resolution Issues
Some domains resolve to both IPv4 (A records) and IPv6 (AAAA records) addresses. If the SSL/TLS certificate on one address (e.g., IPv6) is misconfigured, such as having the wrong hostname, an incomplete chain, or an expired certificate, clients that connect via that protocol will fail SSL verification. This issue often appears inconsistently, depending on whether the client prefers IPv4 or IPv6, making it harder to diagnose.
Solution: Test both IPv4 and IPv6 connections separately:
# IPv4 test
openssl s_client -connect example.com:443 -servername example.com -4
# IPv6 test
openssl s_client -connect example.com:443 -servername example.com -6
If one protocol returns an invalid certificate, update the server or CDN configuration for that IP version so that both IPv4 and IPv6 endpoints present the same correct certificate and full chain. If IPv6 is not in use, consider disabling AAAA records until the SSL configuration is fixed.
Python-Specific SSL Troubleshooting
1. Update certifi
In Python, SSL/TLS verification often relies on the certifi
package that provides an up-to-date bundle of trusted root Certificate Authorities (CAs). If certifi
is outdated, it may be missing newer root certificates or still contain expired ones, causing valid SSL connections to fail. This is especially common when connecting to services that recently switched to a new CA or when running Python in a virtual environment with old dependencies.
Solution: Update certifi
to ensure your Python environment uses the latest CA bundle:
pip install --upgrade certifi
If using a virtual environment, run the update inside that environment. After updating, confirm the active CA file path:
import certifi
print(certifi.where())
This ensures Python uses the refreshed CA bundle for SSL verification.
2. Check Virtual Environment
When using Python virtual environments (venv), each environment maintains its own set of installed packages, including certifi
and other SSL-related libraries. If you update certifi
or SSL packages globally, but your application runs inside a virtual environment, the venv may still be using outdated or missing CA certificates. This can cause SSL verification failures even though the global Python installation is up to date.
Solution: Activate the virtual environment and update dependencies inside it:
# Activate venv (example for Linux/Mac)
source venv/bin/activate
# For Windows
venv\Scripts\activate
# Update certifi and SSL-related packages
pip install --upgrade certifi requests urllib3
After updating, verify which CA file is being used:
import certifi
print(certifi.where())
This ensures the virtual environment is using the latest CA certificates for SSL verification.
3. On Windows
On Windows, Python does not always use the system's built-in certificate store by default. Instead, it often relies on its own bundled certificates from the certifi
package. If these certificates are missing or outdated — for example, after a fresh Python installation — SSL verification can fail. Windows installations of Python include a script (Install Certificates.command
or Install Certificates.ps1
) to set up or refresh trusted CA certificates, but it is sometimes skipped during installation.
Solution: Run the certificate installation script from your Python installation directory:
- Locate the script:
For Python.org installers, it's usually in:
Or
- Double-click it, or run it from Command Prompt / PowerShell.
Additionally, keep certifi
updated:
pip install --upgrade certifi
This ensures Python on Windows can verify SSL/TLS connections using the latest trusted root certificates.
4. Set Custom CA Bundle
In some environments, such as corporate networks, internal APIs, or when using self-signed certificates, the default certificate store may not contain the root Certificate Authority (CA) required to verify the server's SSL/TLS certificate. This results in verification failures, even though the certificate is valid within that specific environment. To solve this, you can point Python or other tools to a custom CA bundle containing the necessary trusted certificates.
Solution: Save the required CA certificate(s) into a .crt
or .pem
file, then set the environment variable so your application uses it:
# Linux / macOS
export REQUESTS_CA_BUNDLE=/path/to/custom-ca-bundle.crt
# Windows (PowerShell)
setx REQUESTS_CA_BUNDLE "C:\path\to\custom-ca-bundle.crt"
You can also set CURL_CA_BUNDLE
for tools like curl
.
For Python requests library, you can pass it directly in code:
import requests
response = requests.get('https://example.com', verify='/path/to/custom-ca-bundle.crt')
This ensures SSL verification succeeds by using the correct trusted CA list for your environment.
How to Detect SSL Certificate Problems
When an SSL/TLS connection fails, the error message alone often doesn't reveal the exact cause. The issue could be due to an expired certificate, a hostname mismatch, a missing intermediate, or a problem with the trust store. Without proper inspection, troubleshooting becomes guesswork. Detecting SSL certificate problems involves checking the certificate's validity, chain of trust, issuer, supported TLS versions, and whether the server is serving the correct certificate for the requested domain.
You can diagnose SSL certificate issues with these steps:
1. View the full certificate chain
openssl s_client -connect example.com:443 -servername example.com –showcerts
2. Check certificate expiration
openssl x509 -in cert.pem -noout –enddate
3. Verify against a specific CA bundle
openssl verify -CAfile /path/to/ca-bundle.crt cert.pem
4. Test supported TLS versions
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
5. Use online tools:
How to Prevent SSL Errors
1. Automate renewals with Let's Encrypt or other CAs
Manually renewing SSL/TLS certificates increases the risk of forgetting, leading to unexpected expirations and downtime. Many incidents occur simply because certificates have expired unnoticed.
Use automated renewal tools, such as Certbot for your CA's API, to automatically request, install, and reload certificates before they expire. Schedule renewals at least 30 days before expiration to allow for retries if an update fails.
2. Monitor certificate expiry dates
Even with automation, renewal processes can fail silently due to configuration changes, DNS issues, or CA errors. Without monitoring, you might overlook until the service breaks.
Set up monitoring to alert you when certificates are close to expiry. Use the WebSitePulse SSL monitoring service that checks expiry dates and sends alerts.
3. Keep OS, libraries, and CA bundles updated
Outdated operating systems, SSL libraries (like OpenSSL), and CA bundles may lack new trusted roots or contain expired ones, causing valid certificates to fail verification.
Regularly apply OS updates and update SSL libraries (apt upgrade
, yum update
, brew upgrade
) and CA bundles (update-ca-certificates
or pip install --upgrade certifi
). This ensures your system trusts the latest Certificate Authorities and supports modern TLS.
4. Enforce TLS 1.2+ only
Older TLS versions (1.0 and 1.1) are deprecated and may be rejected by modern clients, causing connection failures. Using outdated versions also introduces serious security vulnerabilities.
Configure servers to support only TLS 1.2 and TLS 1.3. Disable older protocols in your web server, application, or load balancer configuration. For example, in Nginx:
ssl_protocols TLSv1.2 TLSv1.3;
Also, ensure clients and libraries are updated to support these protocols.
5. Standardize certificate configs across environments
If development, staging, and production environments use different certificate configurations, errors may only appear when code is deployed to production — making them harder to catch early.
Use the same certificate settings, trust stores, and TLS configurations across all environments. Store configuration in version control, and test SSL/TLS connections in lower environments with production-like setups to detect issues before release.
Conclusion
SSL certificate verification failures signal broken trust between client and server. By identifying the cause, applying the proper fix, and following prevention best practices, you can ensure secure, reliable connections and protect sensitive data from potential attacks.
Start Monitoring Your SSL Certificate Now!
Frequently Asked Questions (FAQ)
Is SSL the same as TLS?
No. SSL is the older protocol; TLS is its secure replacement (TLS 1.2/1.3 are current standards).
Is it safe to disable SSL verification?
No, except for temporary debugging in a safe environment. It makes connections vulnerable to MITM attacks.
How can I check if a server's certificate matches its hostname?
Run:
openssl s_client -connect example.com:443 -servername example.com
and inspect the CN/SAN fields.
Can an antivirus cause SSL errors?
Yes. Some antivirus tools intercept HTTPS traffic. Disable HTTPS scanning or import their CA.
Is it safe to use 'verify=False' in Python' requests' for debugging?
While using 'verify=False' can temporarily bypass Python SSL issues for debugging purposes, it should be done with extreme caution and only in non-production environments. It completely disables SSL certificate validation, making your connection vulnerable to Man-in-the-Middle attacks and compromising data integrity. Never deploy code with 'verify=False' to a production system.
How can I check a server's SSL certificate chain?
You can use the 'openssl' command-line tool, which is widely available on most Linux/macOS systems and can be installed on Windows. Run:
openssl s_client -connect example.com:443 -showcerts
(replace example.com with your target domain) to display the full certificate chain presented by the server, including root and intermediate certificates.
My system clock is correct, but I still get certificate errors. What else could it be?
Even with a correct system clock, issues can arise if the server's clock is significantly off, or if a certificate in the trust chain has expired or been revoked. Also, network intermediaries like network proxies that perform SSL inspection can present their own certificates, which your system might not trust.
What is a trusted root certificate, and why is it important?
A trusted root certificate is a digital certificate issued by a Certificate Authority (CA) that is pre-installed and implicitly trusted by your operating system or web browser. It forms the anchor of the trust chain. If the root certificate associated with a server's certificate is not trusted or is missing, the client cannot verify the server's identity, leading to verification failures and preventing secure connections.