- OpenSSL
- Exact text checked with the real tool
verify error:num=20:unable to get local issuer certificate
Also seen in: openssl s_client, openssl verify, Ruby, PHP, anything built on OpenSSL
In one sentence
OpenSSL found a certificate whose issuer is neither in the chain the server sent nor in your trust store; the depth number tells you which link is missing.
Where you see it
In the output of openssl s_client while you test a server, and in openssl verify while you test certificate files. The number and text are OpenSSL’s X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, listed in the OpenSSL verification options documentation.
A server whose chain ends at a root you do not trust:
$ openssl s_client -connect git.example.com:443 -servername git.example.com </dev/null
Connecting to 192.0.2.10
CONNECTED(000001BC)
depth=1 O=Example Corp, CN=Example Corp Issuing CA
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN=git.example.com
verify return:1
---
Certificate chain
0 s:CN=git.example.com
i:O=Example Corp, CN=Example Corp Issuing CA
1 s:O=Example Corp, CN=Example Corp Issuing CA
i:O=Example Corp, CN=Example Corp Root CA
...
Verify return code: 20 (unable to get local issuer certificate)
The same error from openssl verify:
$ openssl verify -CAfile root.pem server.pem
CN=git.example.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error server.pem: verification failed
s_client reports the error and carries on, so you can still read the chain. Programs that use OpenSSL (curl, Python, Ruby, PHP) stop at this point and show their own version of the message.
What it means
OpenSSL builds a certificate chain from the server’s certificate upwards. For each certificate it needs the issuer’s certificate: from what the server sent, or from the local trust store. At the depth shown, it found a certificate whose issuer it could not find anywhere. The depth tells you where: depth=0 is the server’s own certificate, depth=1 the first certificate above it.
Likely causes
depth=0: the server does not send its intermediate
If the error is at depth=0 and s_client follows it with verify error:num=21:unable to verify the first certificate, the server sent only its own certificate. You see a single 0 s: entry under “Certificate chain”.
Fix: configure the server with its certificate followed by the intermediate certificate:
cat server.crt issuing-ca.crt > fullchain.pem
Use fullchain.pem in nginx’s ssl_certificate or Apache’s SSLCertificateFile; on IIS, install the intermediate in the computer’s “Intermediate Certification Authorities” store. More detail: verify error:num=21.
When you test certificate files, the same happens if you forget to give openssl verify the intermediate:
openssl verify -CAfile root.pem -untrusted issuing-ca.pem server.pem
depth=1 or higher: the root is not in your trust store
The server sent its intermediate, but the root that signed it is not one you trust. This is typical for company CAs and TLS-inspection proxies. Test with the root you expect:
openssl s_client -connect git.example.com:443 -servername git.example.com -CAfile corp-root.pem </dev/null 2>/dev/null | grep 'Verify return code'
If this prints Verify return code: 0 (ok), the chain is fine and only trust is missing. Add the root to the system store (/usr/local/share/ca-certificates/ and update-ca-certificates on Debian and Ubuntu, /etc/pki/ca-trust/source/anchors/ and update-ca-trust extract on RHEL), and to the stores of the programs that keep their own (Java, Python’s certifi, Node.js).
OpenSSL has no trust store at all
If every site fails, even public ones, your OpenSSL may not find any trust store. Check where it looks:
openssl version -d
This prints the OPENSSLDIR. If that directory has no cert.pem or certs/ with the public roots, install your system’s CA bundle, or pass one explicitly with -CAfile /etc/ssl/certs/ca-certificates.crt (the path on Debian and Ubuntu).
Check yours
Paste the certificates from openssl s_client -showcerts. The checker shows each link and which issuer is missing.
Learn why
- Certificate chains and path validation: depth, issuers and how the path is built.
- Who do we trust? CAs, trust stores and self-signed certificates.
- The same problem in other tools: curl, Python, npm.
Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.