Skip to content

/errors/openssl/unable-to-get-local-issuer-certificate

unable to get local issuer certificate (OpenSSL verify error 20)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · OpenSSL 3.5.7 9 Jun 2026 (Library: OpenSSL 3.5.7 9 Jun 2026)updated 2026-10-20
tool
OpenSSL
exit code
2
versions
OpenSSL 1.1.1, OpenSSL 3.x, OpenSSL 4.0
os
linux, macos, windows

unable to get local issuer certificate (X509 verify error 20) means OpenSSL found the certificate but not the certificate of the CA that signed it, neither in the chain it received nor in the local trust store. Provide the missing CA or intermediate certificate.

Reproduce the error

A leaf certificate signed by a private CA, verified without telling OpenSSL about that CA:

bash
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout ca.key -out ca.pem -subj "/CN=Example Root CA" -days 30 2>/dev/null
openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout leaf.key -out leaf.csr -subj "/CN=app.example.test" 2>/dev/null
openssl x509 -req -in leaf.csr -CA ca.pem -CAkey ca.key -out leaf.pem -days 10 2>/dev/null
openssl verify leaf.pem

Output · exit 2

CN=app.example.test
error 20 at 0 depth lookup: unable to get local issuer certificate
error leaf.pem: verification failed

Fix: provide the issuer

bash
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout ca.key -out ca.pem -subj "/CN=Example Root CA" -days 30 2>/dev/null
openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout leaf.key -out leaf.csr -subj "/CN=app.example.test" 2>/dev/null
openssl x509 -req -in leaf.csr -CA ca.pem -CAkey ca.key -out leaf.pem -days 10 2>/dev/null
openssl verify -CAfile ca.pem leaf.pem

Output

leaf.pem: OK

The same idea applies to every client: curl --cacert ca.pem, Python requests.get(url, verify="ca.pem"), Node.js NODE_EXTRA_CA_CERTS=ca.pem.

When the server is at fault

If public clients fail too, the server probably omits its intermediate certificate. Check what it sends:

bash
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null

A correct server sends the leaf and every intermediate up to (not including) the root. With Let's Encrypt and nginx, point ssl_certificate at fullchain.pem, not cert.pem.

Sources