opdeck / blog / ssl-certificate-not-trusted-fix-guide

How to Fix SSL Certificate Not Trusted Issues: A Complete Guide

October 1, 2026 / OpDeck Team
SSL IssuesWeb SecurityCertificate FixTrust ErrorsHTTPS

If you've landed here because your browser is throwing an "SSL certificate not trusted" error — or your users are seeing scary security warnings on your site — you're in the right place. An SSL certificate not trusted fix isn't always straightforward because the root cause can vary significantly: an expired cert, a broken certificate chain, a misconfigured server, or even a system clock issue. This guide walks you through every major cause and gives you concrete steps to resolve each one, whether you're a site owner, developer, or IT administrator.


Why SSL Certificates Fail Trust Validation

Before jumping into fixes, it helps to understand what "trust" actually means in the context of SSL/TLS. When a browser connects to your site, it checks three things:

  1. Is the certificate valid? — Not expired, not revoked, and issued for the correct domain.
  2. Is the certificate chain complete? — The cert must chain up to a root CA that the browser already trusts.
  3. Does the server configuration match? — The domain on the cert must match the domain being visited.

If any of these checks fail, the browser displays a trust error. The exact error message varies by browser:

  • Chrome: NET::ERR_CERT_AUTHORITY_INVALID or NET::ERR_CERT_DATE_INVALID
  • Firefox: SEC_ERROR_UNKNOWN_ISSUER or MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT
  • Safari: Safari Can't Verify the Identity of the Website
  • Edge: DLG_FLAGS_INVALID_CA or DLG_FLAGS_SEC_CERT_DATE_INVALID

Understanding which error you're seeing narrows down the fix considerably.


Common Causes of SSL Certificate Trust Errors

1. Expired SSL Certificate

This is the most common cause. SSL certificates have a finite validity period — typically 90 days for Let's Encrypt certificates and up to one year for commercial CAs. Once expired, every browser will reject the certificate immediately.

How to check:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -dates

This outputs:

notBefore=Jan  1 00:00:00 2024 GMT
notAfter=Apr  1 00:00:00 2024 GMT

If notAfter is in the past, your certificate has expired.

You can also use the SSL Certificate Checker on OpDeck to instantly verify expiration dates, issuer details, and the full certificate chain without running terminal commands.

Fix: Renew your certificate. For Let's Encrypt users:

sudo certbot renew --force-renewal
sudo systemctl reload nginx
# or
sudo systemctl reload apache2

For commercial certificates, log into your CA's dashboard and initiate a renewal. After downloading the new cert files, update your server configuration and reload.


2. Incomplete Certificate Chain (Missing Intermediate Certificates)

This is arguably the most misunderstood SSL trust error. Your certificate is valid, but the browser can't build a complete chain of trust from your cert up to a trusted root CA.

Here's why it happens: Root CAs don't sign your certificate directly. They sign intermediate certificates, and those intermediate certs sign your certificate. Your server needs to serve both your end-entity certificate and the intermediate certificate(s). If you only upload your domain certificate, browsers that don't have the intermediate cached will fail.

How to check for chain issues:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com

Look at the Certificate chain section. A complete chain typically shows 2–3 certificates. If you only see one, you're missing intermediates.

Alternatively, use a tool like SSL Labs or the SSL Certificate Checker to see exactly which certificates are being served and whether the chain is complete.

Fix for Nginx:

Concatenate your domain certificate with the intermediate certificate(s) into a single bundle file:

cat your_domain.crt intermediate.crt > bundle.crt

Then in your Nginx config:

ssl_certificate /etc/nginx/ssl/bundle.crt;
ssl_certificate_key /etc/nginx/ssl/your_domain.key;

Fix for Apache:

SSLCertificateFile /etc/apache2/ssl/your_domain.crt
SSLCertificateKeyFile /etc/apache2/ssl/your_domain.key
SSLCertificateChainFile /etc/apache2/ssl/intermediate.crt

Reload Apache after making changes:

sudo systemctl reload apache2

Fix for IIS (Windows Server):

In IIS, you typically install the intermediate certificate into the Intermediate Certification Authorities store using the Certificate Manager (certmgr.msc), then re-bind the certificate to your site.


3. Self-Signed Certificate

A self-signed certificate is one you generated yourself rather than obtaining from a trusted CA. These are perfectly fine for local development and internal tools, but they will always trigger trust errors in public-facing browsers because no recognized CA has vouched for them.

How to identify a self-signed cert:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -issuer -subject

If the issuer and subject fields are identical, it's self-signed.

Fix for production sites: Replace the self-signed cert with one from a trusted CA. Let's Encrypt is free and widely trusted:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Fix for internal/development environments: You have two options:

  1. Add your self-signed CA to the trusted store on all client machines (appropriate for internal tools)
  2. Use a tool like mkcert which creates locally trusted development certificates
# Install mkcert
brew install mkcert  # macOS
mkcert -install
mkcert yourdomain.local

This creates certificates trusted by your local machine without browser warnings.


4. Domain Mismatch

The certificate was issued for a different domain than the one being accessed. Common scenarios:

  • Certificate issued for example.com but user visits www.example.com
  • Certificate issued for old-domain.com after a domain migration
  • Wildcard certificate for *.example.com but visitor goes to example.com (the apex domain isn't covered by wildcards)

How to check:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -text | grep -E "Subject:|DNS:"

Look at the Subject Alternative Names (SANs) section. Every domain the certificate covers will be listed there.

Fix: Reissue the certificate with the correct domain(s) included. With Certbot:

sudo certbot --nginx -d example.com -d www.example.com

For wildcard certificates that need to cover the apex domain, you must explicitly include both:

sudo certbot --nginx -d example.com -d "*.example.com"

5. Incorrect System Clock (Client-Side Issue)

Sometimes the SSL certificate trust error isn't on the server at all — it's on the client machine. SSL validation is time-sensitive. If a client's system clock is significantly off (even by a few hours), the browser may believe a valid certificate is expired or not yet valid.

How to diagnose: Ask users reporting the error to check their system time. On Windows, right-click the clock in the taskbar and select "Adjust date/time." On macOS, go to System Preferences > Date & Time.

Fix: Sync the system clock:

# Linux
sudo timedatectl set-ntp true
sudo systemctl restart systemd-timesyncd

# Or manually sync with NTP
sudo ntpdate pool.ntp.org

On Windows, open an elevated command prompt:

w32tm /resync /force

6. Certificate Revocation

Certificate Authorities can revoke certificates before they expire if the private key is compromised or if the certificate was issued in error. Browsers check revocation status via CRL (Certificate Revocation List) or OCSP (Online Certificate Status Protocol).

How to check revocation status:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -text | grep -A 4 "CRL Distribution Points"

Then check the OCSP URL:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -ocsp_uri

Fix: If your certificate has been revoked, you need to request a new one from your CA. If the revocation was due to a compromised private key, generate a new key pair:

openssl genrsa -out new_private.key 2048
openssl req -new -key new_private.key -out new_request.csr

Submit the CSR to your CA to get a fresh certificate.


7. Outdated Root Certificate Store

Browsers and operating systems maintain a list of trusted root CAs. Occasionally, a CA is added to or removed from this list. If a user is running a very old OS or browser that doesn't recognize a newer CA (like Let's Encrypt's ISRG Root X1), they'll see trust errors.

This was a significant issue in September 2021 when Let's Encrypt's old cross-signed root (DST Root CA X3) expired, causing failures on older Android devices and some Linux systems.

Fix for server operators:

Enable OCSP stapling to reduce reliance on client-side root stores:

# Nginx
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

For Let's Encrypt, consider using a certificate that chains to a root compatible with older clients.

Fix for end users: Update the operating system. On Debian/Ubuntu servers:

sudo apt update && sudo apt install ca-certificates
sudo update-ca-certificates

On CentOS/RHEL:

sudo yum update ca-certificates

How to Perform a Full SSL Certificate Trust Audit

Rather than guessing which issue you have, run a systematic check. Here's a complete diagnostic sequence:

Step 1: Check the Certificate Details

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com </dev/null 2>/dev/null | openssl x509 -noout -text

This outputs everything: validity dates, issuer, subject, SANs, key usage, and extensions.

Step 2: Verify the Full Chain

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com -showcerts </dev/null 2>/dev/null

Count the number of certificates in the output. You should see at least two (your domain cert and at least one intermediate).

Step 3: Test from an External Perspective

Use the SSL Certificate Checker to see what the certificate looks like from outside your network. This catches issues that might be masked by local caching or network configuration.

Step 4: Check TLS Protocol and Cipher Support

nmap --script ssl-enum-ciphers -p 443 yourdomain.com

Old TLS versions (TLS 1.0, TLS 1.1) are deprecated and may cause trust warnings in modern browsers even if the certificate itself is valid.

Step 5: Validate Certificate Against Specific Browsers

Different browsers use different root stores. Chrome uses the OS root store (except on Linux), Firefox has its own built-in root store, and Safari uses macOS/iOS stores. Test across browsers to isolate whether the issue is browser-specific.


Preventing Future SSL Certificate Trust Issues

Once you've applied your SSL certificate not trusted fix, put systems in place to prevent recurrence:

Automate Certificate Renewal

For Let's Encrypt, Certbot installs a cron job or systemd timer automatically. Verify it's active:

sudo systemctl status certbot.timer
# or check cron
sudo crontab -l

For commercial certificates, set calendar reminders 30, 14, and 7 days before expiration. Many CAs also send email reminders.

Monitor Certificate Health Continuously

Set up monitoring that alerts you before a certificate expires or has configuration issues. Many uptime monitoring services include SSL checks. You can also run periodic checks using the SSL Certificate Checker to verify your certificate status, chain completeness, and expiration timeline on demand.

Implement HSTS Carefully

HTTP Strict Transport Security tells browsers to always use HTTPS for your domain. Once set, it's very difficult to roll back, so make sure your SSL setup is solid before enabling it:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Start with a short max-age (like 300 seconds) for testing, then increase it once you're confident everything is working correctly.

Keep Your Server Software Updated

TLS configuration recommendations change over time. Older cipher suites get deprecated, new vulnerabilities are discovered. Keeping Nginx, Apache, or your load balancer updated ensures you're using current TLS best practices.


Quick Reference: SSL Trust Error Codes and Fixes

Error Code Cause Fix
NET::ERR_CERT_DATE_INVALID Expired cert or wrong system clock Renew certificate or sync client clock
NET::ERR_CERT_AUTHORITY_INVALID Self-signed or unknown CA Get cert from trusted CA or install CA cert
SEC_ERROR_UNKNOWN_ISSUER Missing intermediate certificate Add intermediate cert to server config
NET::ERR_CERT_COMMON_NAME_INVALID Domain mismatch Reissue cert with correct SANs
ERR_CERT_REVOKED Certificate revoked Request new certificate from CA
MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED Outdated root store Update OS/browser

Conclusion

Fixing an SSL certificate that isn't trusted comes down to methodically identifying which part of the trust chain is broken. Whether it's an expired certificate, a missing intermediate, a domain mismatch, or a client-side clock issue, each problem has a clear, actionable solution. The key is running the right diagnostic commands to pinpoint the exact failure before attempting a fix.

Start your SSL certificate not trusted fix by running a quick check with OpDeck's SSL Certificate Checker — it gives you an instant, detailed view of your certificate's validity, chain completeness, issuer, and expiration date without needing to touch the command line. From there, use the solutions in this guide to address whatever issue you find. Once fixed, set up automated renewal and monitoring so you're never caught off guard by a certificate problem again.