Nginx server sending wrong intermediate chain

Chrome connects to my https websites, but openssl is throwing cert issues for the same sites

CONNECTED(00000003)
depth=1 C = US, O = Let's Encrypt, CN = YR1
verify error:num=20:unable to get local issuer certificate
verify return:1

Do you have some commands that I can run to fix this issue?

You should have opened a new topic even if the symptoms are the same as the original poster of this topic. Then, fill up the questioner.

A well configured https website when connecting to via openssl looks the following:

CONNECTED(00000003)
depth=3 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=2 C = US, O = ISRG, CN = Root YR
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = YR1
verify return:1

The HTTPS server sends only the first certificate from the certificate chain, not the whole chain. That is the problem.

I doubt very much that a program exists that would fix any kind of https server having that issue. That is why filling up the questioner is a good start.

Fix for my Nginx running on ubuntu

  1. Look here for the 2 YR cert URLs Chains of Trust - Let's Encrypt
  2. Download the 1st cert
    wget -O /usr/local/share/ca-certificates/letsencrypt-root-yr.crt https://letsencrypt.org/certs/gen-y/root-yr.pem
  3. Download the 2nd cert
    wget -O /usr/local/share/ca-certificates/letsencrypt-root-yr-by-x1.crt https://letsencrypt.org/certs/gen-y/root-yr-by-x1.pem
  4. Run update-ca-certificates

If this help solved your issue quickly, give it a like or something so that it can help others.

That is the bad way to go. Getting around on every client individually, when the server is broken.

How do those commands of mine fix which client?

The host on which you executed those commands, will be able to connect to the https server via openssl s_client (that is your own client host) with successfully verifying the HTTPS connection.

  1. Commands ran on the 1 problematic HTTPS SERVER that I have
  2. openssl/curl CLIENT running on any machine now connects to this previously problematic server without issues anymore
  3. Utterly confused by everything you are saying, if you have a better solution to fix the problematic server, show it

After running the command to update the local certificate trust anchor store, what is the output of the openssl s_client command?

CONNECTED(00000003)
depth=2 C = US, O = ISRG, CN = Root YR
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = YR1
verify return:1
depth=0 CN = REDACTED
verify return:1

Hmmm... Now, I am confused too. I have not heard about any https server that dynamically constructs the certificate chain to send, from the local trust anchor store.

It happened once before several years ago, that's why I knew there is a set of commands that can fix the problem. If you ever find out why, please update here so that we all can learn from it. Got to run.

I thought Windows servers often did that, for whatever that's worth.

when using fullchain there should not be a need to import the root into your ca-certificates.

you also imported a cross signed intermediate which can be replaced at any time without notice.

        ssl_certificate /path/to/signed_cert_plus_intermediates;        
        ssl_certificate_key /path/to/private_key;

like suggested here.

I moved your issue to its own thread. As noted earlier, the solution is not related to the thread you posted on. We like each unique problem to be its own so we can provide specific advice.

My fellow volunteers have explained the problem well. I am also surprised that modifying your CA Certificates trust store could affect what an nginx server sends out. Normally nginx only sends what is described by the ssl_certificate statement. In fact, I have never seen it do otherwise.

If you want a complete answer to your problem we'll need more info. Start by showing the nginx server block, describe the ACME Client you are using, and the o/s it runs on including the version.

We'd be happy to help you fix your server problem. Once we get more info we can proceed. You didn't fix it properly "several years ago" which is why it remains a problem today. And will be a problem in the future when Let's Encrypt next changes its chain.

The way to truly fix the problem is to instruct Nginx to serve the correct chain of certificates, and doesn't involve any mucking about with the OS's certificate trust store. Since you haven't said which client you're using to manage your certificates, we can't say for sure, but popular clients like certbot and acme.sh save a fullchain file, which consists of the cert sent by Let's Encrypt, combined with the intermediate chain also sent by Let's Encrypt. That's what you'd point to in your Nginx config as ssl_certificate.

  1. I run my own PHP client Live cert does not match with key - #3 by bilogic

  2. I save the fullchain cert as-is issued by LE's servers

  3. I use nginx proxy manager (NPM) to point to the fullchain cert and key

  4. But on connecting to NPM loaded with LE's YR certs, I get verify error:num=20:unable to get local issuer certificate

You mean using the nginx server setup by NPM I think.

In any case, would you please show the nginx server block handling this domain name?

  1. GitHub - NginxProxyManager/nginx-proxy-manager: Docker container for managing Nginx proxy hosts with a simple, powerful interface · GitHub
  2. It is UI based, I have no idea how to bring out its blocks
  3. All I know is that it accepts 2 files for each domain (fullchain and key)
total 18
drwxr-xr-x  2 root root    4 Nov  6  2025 ./
drwxr-xr-x 17 root root   17 Mar 25 12:06 ../
-rw-r--r--  1 root root 3968 Nov  6  2025 fullchain.pem
-rw-r--r--  1 root root 3272 Nov  6  2025 privkey.pem
root@ops-work-112:/docker/compose/nginx-proxy-work/data-docker/data/custom_ssl#
  1. When these 2 files are by LE's YR certs, verify error:num=20:unable to get local issuer certificate
  2. When I replace these 2 files with ones from zerossl, no errors

I am not an NPM expert but does this directory exist? If so show ls -l for it. This should (might) have your nginx server config files so we can see what is actually happening

/docker/compose/nginx-proxy-work/data-nginx

And what are the contents of fullchain.pem? And why is it dated Nov. 6? Either something's badly wrong with your server's clock (which would also cause the cert verification errors), you're serving a very old cert, or you're showing us a very old directory listing.