Why am I getting “unable to get local issuer certificate”?

Your app can reach the website, but it can’t connect its certificate to an issuer it trusts. Here’s how to tell whether the website’s certificate bundle or your app’s trusted certificates need attention.

Why does a website need a certificate chain?

Think of a certificate chain as endorsements on a letter: each signer is vouched for by the next, until you reach someone you already trust. Your app needs that path from the website’s certificate to a trusted root certificate.

Website certificate, missing intermediate certificate, and trusted root in path order. The website supplies the leaf and intermediates; the app trusts the root.

Certificate path

  1. Website certificate

    Also called the leaf, it names the issuer that vouched for the website. The server sends it first.

  2. Intermediate certificate

    This is an issuer between the website and the root. Here, “local issuer” means an issuer certificate the checker needs to find among the certificates available to it.

  3. Trusted root

    The app’s trusted list anchors the path. A root that’s already trusted doesn’t need to be sent by the website.

A missing intermediate breaks the path. Sources and review notes

What happens when the middle certificate is missing?

In our locally generated example, the same website certificate fails without its intermediate and passes when the intermediate is supplied. The website certificate and trusted root stay the same.

Two local OpenSSL checks: without intermediate.pem the issuer is missing; adding -untrusted intermediate.pem returns leaf.pem: OK. Both use root.pem and leaf.pem.

OpenSSL local-file comparison

  1. Without the issuer

    openssl verify -CAfile root.pem leaf.pem reports “error 20 at 0 depth lookup: unable to get local issuer certificate”.

  2. Supply the intermediate

    openssl verify -CAfile root.pem -untrusted intermediate.pem leaf.pem. -untrusted supplies an issuer certificate without trusting it as a root; -CAfile names the trusted root.

  3. The leaf passes

    The result is “leaf.pem: OK”.

In this local-file check, adding the intermediate changes failure to success.

Is a certificate missing, or does your app lack the trusted root?

The error points to an incomplete path; the place to repair it depends on what the website sends and what the failing app trusts. Start with the certificates from the connection that failed.

Illustrated OpenSSL command for displaying server-sent certificates, followed by a decision diagram: missing issuer leads to server bundle repair; issuers present leads to checking app trust.

Server bundle or app trust?

  1. See what the server sends

    With OpenSSL installed, run openssl s_client -connect HOST:443 -servername HOST -showcerts. Replace both HOST values with the website’s hostname. The Certificate chain output lists what that server sent; ask its administrator for this output if you don’t have terminal access.

  2. Compare issuer and subject

    The website certificate’s Issuer should lead to the Subject of an issuer certificate. If that intermediate is absent, the website administrator needs to supply it.

  3. Follow the path to app trust

    If intermediates are present, follow their issuers to the intended root and check the trusted certificates used by the app that failed. A different app’s success doesn’t settle that check.

Server certificates and app trust are separate checks.

Doing it in FluffyBench: inspect a certificate bundle

FluffyBench’s Certificate and public key inspector helps you compare issuer names in public certificate bundles on your device. It matches names; it doesn’t validate a connection or fetch missing certificates.

  1. Certificate and public key inspector task tabs, including Certificate chain.
    Certificate and public key inspector task tabs, including Certificate chain.
    Step 1. In FluffyBench's Certificate and public key inspector, choose Certificate chain.
    1. Choose Certificate chain.
  2. Certificate chain input with Choose file and a place to paste public PEM blocks.
    Certificate chain input with Choose file and a place to paste public PEM blocks.
    Step 2. Paste your public CERTIFICATE blocks, or use Choose file to open the bundle. The public sample shown here contains one website certificate. Leave private keys out.
    1. Choose file opens a public certificate bundle.
    2. Paste CERTIFICATE PEM blocks here.
  3. Issuer relationship reports No matching issuer name in this bundle.
    Issuer relationship reports No matching issuer name in this bundle.
    Step 3. Read Issuer relationship. The public sample shown here leaves out its issuer.
    1. Read the missing issuer-name message.
  4. What's inside result heading with Copy all.
    What's inside result heading with Copy all.
    Step 4. Your report appears in What's inside as you paste. Copy all copies the inspection report.
    1. Copy all copies the inspection report.

Use FluffyBench’s Certificate and public key inspector to compare issuer names in your bundle.

How do you repair a website’s certificate bundle?

For a missing intermediate, configure the server’s bundle with the website certificate first and its issuer certificates afterward. The first certificate must match the server’s private key.

Wrong PEM order puts the intermediate first. Correct order pairs the website certificate with the key, followed by intermediates. An abbreviated fullchain.pem illustration shows the two CERTIFICATE blocks in that order.

PEM bundle order

  1. Wrong first certificate

    In nginx, putting the intermediate first can produce “key values mismatch”.

  2. Use the issuer’s chain

    Get the intermediate certificates from the certificate issuer. If you don’t manage the website, send the missing-issuer details to its administrator.

  3. Save the complete PEM blocks

    The fullchain.pem illustration abbreviates the certificate contents. Keep each complete BEGIN CERTIFICATE through END CERTIFICATE block; the private key stays in its separate server file.

Illustration: website certificate first, intermediates afterward.

How do you fix a root your app doesn’t trust?

When the website supplies its intermediates, check the root certificates used by the app that failed. If your organization uses a private root, its administrator can arrange trust in that app.

The server supplies the website certificate and intermediates. The app has a separate trusted-root list. Sending a root from the server does not add it to that list.

Where app trust belongs

  1. Server-supplied certificates

    A complete server bundle supplies the path toward a root; it doesn’t decide which roots your app trusts.

  2. Use the failing app’s trust settings

    Ask your organization’s administrator to install its approved private root in the trusted list used by that app. A different app’s trusted list may differ.

  3. Sending isn’t trusting

    Adding a root to the server’s bundle doesn’t make the app trust it.

The app’s trusted list is a separate part of the repair.

How do you check that the certificate repair worked?

After applying the repair, repeat the original request from the app that failed.

Apply the corrected server or app configuration, then repeat the failing request in the original app with certificate verification enabled.

Repair checks

  1. Apply the repair

    Deploy the corrected server bundle, or apply the approved app trust change, using the relevant configuration process.

  2. Repeat the original request

    Use the same app and website that gave you the error.

  3. Keep verification on

    Turning it off hides the error without repairing the path; Node.js warns against setting NODE_TLS_REJECT_UNAUTHORIZED to zero.

Finish with the original app and connection.
Search FluffyBench