SSL certificate not trusted: fix the chain and self-signed certificates
When a browser, a command-line tool or a security scanner says your SSL certificate cannot be trusted, it means it could not link your certificate to a root it already trusts. Visitors see a full-page warning, payment providers and apps may refuse to connect, and scanners report it as a vulnerability. The cause is nearly always on your server: a missing intermediate certificate, a self-signed or control panel default certificate, or a private authority. This guide explains what the warning means, how to diagnose it with openssl and curl, how to serve the full chain on nginx, Apache, Plesk, cPanel and IIS, why a certificate ends up self-signed, and how to fix the unable to get local issuer certificate error.
- What SSL certificate not trusted means
- Why your SSL certificate is not trusted
- How to diagnose an untrusted certificate
- Fixing the intermediate chain on your server
- Replacing a self-signed or default certificate
- Fixing unable to get local issuer certificate
- The fix, step by step
- Edge cases worth knowing
- Keeping the chain trusted
- Questions and answers
What SSL certificate not trusted means
A browser or client trusts a certificate only if it can build a chain from your certificate, through one or more intermediate certificates, up to a root certificate already stored in its trust store. Roots come with the operating system or browser. Intermediates are meant to be sent by your server, together with your own certificate, every time a connection is made.
example.com (your certificate, the leaf)
issued by Example CA R1 (intermediate, sent by your server)
issued by Example Root CA (root, already on the visitor's device)
When any link is missing or unknown, the result is a not trusted warning. Browsers show it as NET::ERR_CERT_AUTHORITY_INVALID in Chrome and SEC_ERROR_UNKNOWN_ISSUER in Firefox. Command-line tools such as curl and git report SSL certificate problem: unable to get local issuer certificate. Vulnerability scanners list it as a finding called SSL Certificate Cannot Be Trusted, usually rated medium.
This is a different problem from a certificate issued for the wrong name or one that has expired, although scanners sometimes report them together. Name problems are covered in the hostname mismatch guide, and the SSL errors guide covers the wider set.
Why your SSL certificate is not trusted
| Cause | How it shows up | Fix |
|---|---|---|
| Missing intermediate certificate | Works in some desktop browsers, fails in curl, scanners, some phones and apps | Serve the full chain file |
| Self-signed certificate | Fails everywhere; issuer is the same as the subject | Replace with a certificate from a public CA |
| Control panel or server default certificate | Issuer is Plesk, cPanel, localhost or a snakeoil certificate | Issue a real certificate for the domain, check the site configuration |
| Private or internal CA | Trusted inside the organisation, not trusted outside it | Use a public CA for public sites |
| Chain in the wrong order or wrong intermediate | Intermittent or client-specific failures | Rebuild the chain file, leaf first |
| Old client trust store | Only old devices or old software fail | Update the client; consider the chain your CA recommends |
| Interception on the client side | Issuer is an antivirus product or company proxy | Nothing to fix on the server |
Why is my SSL certificate self-signed?
Few people set out to use a self-signed certificate. It usually appears because the server is using a placeholder. Plesk and cPanel create a default certificate for new domains until a real one is issued. Linux web servers often ship with a test certificate, such as ssl-cert-snakeoil.pem on Debian and Ubuntu. And if the server cannot match the request to your site, for example because the site has no configuration for IPv6 or the request carries the wrong server name, it falls back to the default site and its certificate. In each case the cure is a real certificate on the right site configuration, not trust settings on visitors' devices.
Why it works in your browser but not for others
Some browsers can fetch a missing intermediate by themselves, using an address in the certificate, or remember intermediates from other sites. That hides a broken chain on your desktop. curl, git, payment providers, monitoring services, many apps and security scanners do not do this, so they report the certificate as untrusted.
How to diagnose an untrusted certificate
Use openssl from any machine. Always include -servername, so the server knows which site you want:
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
Look at two parts of the output. The Certificate chain block lists each certificate sent, numbered from 0. Number 0 is your certificate; number 1 should be its issuer. If only 0 is listed, the intermediate is missing. Then look at the verify result near the end:
| Verify return code | Meaning |
|---|---|
| 0 (ok) | Chain is complete and trusted |
| 18 (self-signed certificate) | The leaf signed itself |
| 19 (self-signed certificate in certificate chain) | The chain ends in a root this client does not trust |
| 20 (unable to get local issuer certificate) | The issuer is not sent and not in the trust store |
| 21 (unable to verify the first certificate) | Typically the intermediate is missing |
Print the issuer and subject of what the server sends:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
If the subject and issuer are the same, it is self-signed. If the issuer names your control panel or a test name, the server is serving a default certificate. Repeat the test over IPv6 with -6 if the domain has an AAAA record, because a separate configuration there is a common source of default certificates.
curl is a quick second check, because it does not fill in missing intermediates:
curl -sS -o /dev/null https://example.com/ && echo trusted
Fixing the intermediate chain on your server
The fix for a missing intermediate is to configure the server with a file that contains your certificate followed by the intermediate certificates, in that order. You do not need to include the root.
Building the chain file
If your CA sent separate files, join them, leaf first:
cat example_com.crt Example_CA_R1.crt > example_com_fullchain.crt
Let's Encrypt already provides this as fullchain.pem. Use that, not cert.pem.
nginx
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Apache
From Apache 2.4.8, put the full chain in SSLCertificateFile. On older versions, use SSLCertificateChainFile for the intermediates.
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Test the configuration and reload rather than restart, so live connections are not dropped:
sudo nginx -t && sudo systemctl reload nginx
sudo apachectl configtest && sudo systemctl reload apache2
Plesk and cPanel
In Plesk, Let's Encrypt certificates are installed with their chain. For a certificate bought elsewhere, upload the intermediate into the CA certificate field when you add the certificate on the SSL/TLS Certificates screen. In cPanel, paste the intermediate into the Certificate Authority Bundle box under Install an SSL Website.
IIS
On Windows, import the intermediate into the Intermediate Certification Authorities store of the local computer, then rebind the site. The IIS bindings guide covers the binding side.
Replacing a self-signed or default certificate
A self-signed certificate cannot be made trusted by changing your server; it has to be replaced. For any public site, a free certificate from Let's Encrypt is enough:
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot --apache -d example.com -d www.example.com
In Plesk, open the domain, choose SSL/TLS Certificates and install a Let's Encrypt certificate covering the domain and its www alias. In cPanel, run AutoSSL. If the panel cannot issue one, the certificate cannot be issued guide explains the usual DNS and validation problems.
If the new certificate is installed but the self-signed one still appears, the request is reaching another site configuration. Check that every IP address the domain resolves to, including IPv6, has a matching configuration, and that the server name in that configuration matches the host visitors use.
Fixing unable to get local issuer certificate
The unable to get local issuer certificate message comes from the client. It means the client could not find the issuer of the certificate it was given, either because the server did not send it or because the client's own trust store does not contain the root.
Work out which side it is with the openssl chain test above. If the chain is complete and verifies with code 0 elsewhere, the problem is on the machine running curl, git, PHP or Python:
- Out-of-date CA bundle. Update the operating system's CA certificates package, for example
sudo apt install --only-upgrade ca-certificateson Debian or Ubuntu. - Git on Windows. Git can use its own bundle instead of the Windows store.
git config --global http.sslBackend schannelmakes it use the Windows store. - Company proxy. An inspecting proxy replaces certificates with its own. Its root must be added to the client's trust store by whoever manages the network.
Never fix this by turning verification off with options such as -k or sslVerify false. That removes the check entirely.
The fix, step by step
Step 1
Confirm which host and port fail
Note the exact host name and port in the warning or scanner finding, for example example.com:443 or a mail service on another port. Open the host in Chrome and Firefox and record the error code. Check whether the problem affects one host, every host on the server, or only some devices. You are done when you have a list of host and port pairs to fix, rather than a general sense that SSL is broken.
Step 2
Inspect the chain with openssl
Run openssl s_client -connect host:443 -servername host -showcerts for each pair. Count the certificates in the chain block and read the verify return code. Then print the subject and issuer of the leaf. Note whether it is self-signed, a panel default, missing its intermediate or a fully trusted chain. Repeat with -6 if the domain has an IPv6 address, because the result can differ.
Step 3
Replace any self-signed certificate
If the subject and issuer match, or the issuer is a panel or test name, install a public certificate. Run Certbot with every host name, install Let's Encrypt in Plesk, or run AutoSSL in cPanel. Then repeat the openssl test. If the old certificate still appears, find the site configuration that is actually answering, such as an IPv6 or default virtual host, and fix that.
Step 4
Build a full chain file
If only your certificate is sent, create a chain file with your certificate first and the intermediates after it, joining them with cat if your CA supplied separate files. With Let's Encrypt, use fullchain.pem. Check the file with openssl crl2pkcs7 -nocrl -certfile fullchain.crt | openssl pkcs7 -print_certs -noout, which lists each certificate and its issuer, in order. The first entry should be your own certificate.
Step 5
Point the server at the full chain
In nginx set ssl_certificate to the full chain file. In Apache 2.4.8 or later set SSLCertificateFile to it. In Plesk or cPanel, add the intermediate in the CA certificate or bundle field. On IIS, import it into the Intermediate Certification Authorities store. Test the configuration with nginx -t or apachectl configtest, then reload the service so the change takes effect.
Step 6
Verify from the outside
Rerun the openssl test and confirm the chain lists your certificate and its issuer and that the verify return code is 0. Run curl -sS -o /dev/null https://example.com/ and check it completes without a certificate error. Test the site on a phone using mobile data. If you use a CDN, test the origin directly too, because scanners and the CDN itself may connect to it.
Step 7
Fix client-side local issuer errors
If the server chain is now complete but a particular machine still reports unable to get local issuer certificate, update that machine's CA bundle, switch Git on Windows to the schannel backend, or install the company proxy's root certificate with help from whoever runs the network. Do not disable verification. Retest the same command on that machine to confirm the error has gone.
Step 8
Rescan and set up monitoring
Run the vulnerability scanner or security audit again on every host and port from your list, and confirm the cannot be trusted finding has cleared. Add an external certificate check to your monitoring that alerts on chain errors as well as expiry, using a client that does not fetch missing intermediates. Repeat the openssl check after every renewal, migration or control panel upgrade.
Edge cases worth knowing
- Behind a CDN. Visitors see the CDN's certificate, so the site looks fine, while the origin may still have a self-signed one. That matters if the CDN is set to validate the origin, and scanners testing the origin will report it.
- Mail and other ports. Scanners test every TLS service, not just the website. A self-signed certificate on a mail or panel port, such as 8443 for Plesk, triggers the same finding.
- Internal systems. For hosts only staff use, a private CA is fine as long as its root is deployed to every device that connects. Do not use it for anything public.
- Extra certificates in the chain. Sending the root, or an old cross-signed intermediate, is rarely harmful but can confuse old clients. Use the chain your CA currently recommends.
Keeping the chain trusted
- Always configure servers with full chain files, and keep the chain with the certificate when you move or copy it.
- After each renewal, run the
openssl s_clientcheck against the live site and confirm a verify return code of 0. - Include certificate checks in monitoring, testing with a client that does not fill in intermediates, such as curl.
- When moving hosts, check the new server's default site and IPv6 configuration before switching DNS. The hosting migration guide covers the checks.
1. What does SSL certificate not trusted mean?
SSL certificate not trusted means the browser or client could not link your certificate to a root certificate it already trusts. The usual reasons are that the server is not sending the intermediate certificate, the certificate is self-signed, or it was issued by a private authority the visitor's device does not know. It does not necessarily mean the connection is unencrypted, but the client cannot confirm who it is talking to, so it shows a warning or refuses to connect at all.
2. Why is my SSL certificate not trusted?
Your SSL certificate is most often not trusted because the server is missing the intermediate certificate or is serving a self-signed or default certificate. Run openssl s_client with the servername option and look at the chain and the verify return code. A single certificate in the chain means the intermediate is missing. Matching subject and issuer means it is self-signed. An issuer naming your control panel means a placeholder certificate is being served instead of your real one.
3. How do I fix SSL certificate cannot be trusted?
To fix a certificate that cannot be trusted, give the server a certificate from a public authority and configure it to send the full chain. Replace any self-signed or default certificate with a Let's Encrypt or commercial one. Point nginx at fullchain.pem, put the chain in Apache's certificate file, or add the intermediate in Plesk, cPanel or IIS. Reload the server, then confirm openssl reports a verify return code of 0 and that curl connects without errors.
4. How do I fix the SSL certificate cannot be trusted vulnerability?
Scanners raise the SSL certificate cannot be trusted vulnerability when any TLS service on the host presents a chain they cannot verify. Fix it on every listed port, not just the website: web, mail, control panel and admin ports often have their own self-signed certificates. Install trusted certificates with complete chains on each service, rescan, and check the finding clears. For services only staff use, a private authority is acceptable if every device trusts its root.
5. What does SSL certificate problem unable to get local issuer certificate mean?
This error means the client, such as curl, git or PHP, could not find the certificate that issued the server's certificate. Either the server did not send its intermediate certificate, or the client's own list of trusted roots is missing or out of date. Test the server's chain with openssl from another machine. If the chain is complete there, update the client's CA bundle, switch Git on Windows to the schannel backend, or add a company proxy's root certificate.
6. Why is my SSL certificate self-signed?
Your SSL certificate is usually self-signed because the server is using a placeholder rather than the certificate you meant to install. Control panels such as Plesk and cPanel create a default self-signed certificate for new domains, Linux web servers often ship with a test certificate, and a request that does not match your site configuration, often over IPv6, falls back to the default site. Install a public certificate on the correct site configuration and check every address the domain resolves to.
7. Why does my site work in Chrome but curl says it is not trusted?
Your site works in Chrome but fails in curl because the server is not sending its intermediate certificate, and Chrome is filling the gap itself. Some browsers fetch missing intermediates using a link in the certificate or reuse ones seen on other sites, while curl, scanners, payment providers and many apps do not. The site is still misconfigured, and some visitors and services will fail. Serve the full chain file and curl will connect without complaint.
Run the security audit on aiwebpageseo.com to see whether your certificate is trusted, when it expires and which security headers are missing, so you can fix the chain before visitors or scanners find it.
Open Security Audit Fixes โ