/ โ† Security Audit Fixes / SSL certificate not trusted
In this guide
  1. What SSL certificate not trusted means
  2. Why your SSL certificate is not trusted
  3. How to diagnose an untrusted certificate
  4. Fixing the intermediate chain on your server
  5. Replacing a self-signed or default certificate
  6. Fixing unable to get local issuer certificate
  7. The fix, step by step
  8. Edge cases worth knowing
  9. Keeping the chain trusted
  10. 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

CauseHow it shows upFix
Missing intermediate certificateWorks in some desktop browsers, fails in curl, scanners, some phones and appsServe the full chain file
Self-signed certificateFails everywhere; issuer is the same as the subjectReplace with a certificate from a public CA
Control panel or server default certificateIssuer is Plesk, cPanel, localhost or a snakeoil certificateIssue a real certificate for the domain, check the site configuration
Private or internal CATrusted inside the organisation, not trusted outside itUse a public CA for public sites
Chain in the wrong order or wrong intermediateIntermittent or client-specific failuresRebuild the chain file, leaf first
Old client trust storeOnly old devices or old software failUpdate the client; consider the chain your CA recommends
Interception on the client sideIssuer is an antivirus product or company proxyNothing 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 codeMeaning
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.

โš ๏ธ Do not tell users or customers to install your self-signed certificate or click past the warning. On a public site that trains them to ignore exactly the warning that protects them from fake sites.

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:

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

Keeping the chain trusted

Questions and answers

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.

Check your certificate chain and HTTPS setup

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 โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All Security Audit Fixes  ·  Fix SSL errors  ·  Fix an SSL hostname mismatch  ·  Fix an HSTS error in Chrome or Firefox  ·  Fix a certificate that cannot be issued  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.