Skip to content
RU

Unable to Get Local Issuer Certificate (curl 60, Git, Node.js): How to Fix

What it means: The client could not find, in its own trust store, the issuer of a certificate the server sent.

  1. Check the chain with openssl s_client -showcerts
  2. Server owner: serve the full chain
  3. Client: install or point to the CA bundle
  4. Behind inspection proxies: trust the proxy root

Test your URL now

Runs a full TLS check: handshake, protocol versions, certificate chain, trust and expiry.

Check your site's SSL →

What unable to get local issuer certificate means

This is OpenSSL verification error 20, X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY. The OpenSSL manual describes it as «The issuer certificate could not be found: this occurs if the issuer certificate of an untrusted certificate cannot be found» (X509_STORE_CTX_get_error). «Local» is the key word: the verifier walked up the chain the server sent and, at the top, looked for the next issuer in the client's own trust store and did not find it.

The same error reaches you in different clothes:

  • curl: curl: (60) SSL certificate problem: unable to get local issuer certificate (exit 60, CURLE_PEER_FAILED_VERIFICATION).
  • Git: fatal: unable to access 'https://example.com/repo.git/': SSL certificate problem: unable to get local issuer certificate.
  • Node.js, npm and tools built on them: Error: unable to get local issuer certificate with code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY' (Node.js X509 error codes).
  • Python: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate, covered on the Python page.

It is a trust problem, not a broken connection: the TLS handshake started fine and the client refused to continue.

Three causes and how to tell them apart

CauseHow to recognise itFix
Server sends only its leaf certificate (missing intermediate)Fails for every client that does not fetch intermediates itself; browsers often still workServer: configure the full chain (leaf + intermediates)
Client has no or an outdated CA bundleFails for every HTTPS site on that machine or containerInstall ca-certificates or point the tool at a bundle
TLS-inspecting proxy or antivirus re-signs trafficIssuer is your company, firewall or antivirus, not a public CAAdd that root CA to the client's trust store

Which certificate is the «untrusted» top of the chain decides the case. OpenSSL raises error 20 when the topmost certificate it has is not self-signed and its issuer is not trusted locally (x509_vfy.c). If the top is the leaf itself, the intermediate is missing. If the top is an intermediate from a public CA, the client lacks the root. If the top is issued by «Zscaler», «Fortinet» or your antivirus, the traffic is being inspected.

Browsers hide the first case: Chrome and Safari download a missing intermediate from the URL inside the certificate and Firefox ships known intermediates preloaded, while curl, Git, Node.js and most libraries do neither. That is why «it works in my browser» is the classic symptom of a missing intermediate.

Read the chain the server actually sends

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null | grep -E '^ *[0-9] s:|^ *i:'
 0 s:CN = example.com
   i:C = US, O = Let's Encrypt, CN = R11

One certificate (only depth 0) whose issuer is an intermediate means the server omits the chain. A healthy answer lists the leaf at depth 0 and its intermediate at depth 1. In the full output, verify error:num=20:unable to get local issuer certificate followed by Verify return code: 21 (unable to verify the first certificate) is the same missing-intermediate case, reported twice because s_client keeps verifying after the first error.

If the chain looks complete but your client still fails, test it against a known bundle to separate «server» from «client»:

curl -v --cacert /etc/ssl/certs/ca-certificates.crt https://example.com/
openssl s_client -connect example.com:443 -servername example.com -CAfile /etc/ssl/certs/ca-certificates.crt </dev/null

How to fix it

  1. Server owner: serve the full chain. In nginx, ssl_certificate must point to the leaf followed by its intermediates (with Certbot, fullchain.pem, not cert.pem). In Apache 2.4.8+, put the intermediates in the same file as the certificate. Reload and re-run the -showcerts check.
  2. Debian, Ubuntu, Alpine containers: install the bundle: apt-get install -y ca-certificates or apk add ca-certificates. Slim images often ship without it.
  3. Private or corporate CA on Linux: copy the root to /usr/local/share/ca-certificates/corp-root.crt and run update-ca-certificates (Debian family); on RHEL family use /etc/pki/ca-trust/source/anchors/ and update-ca-trust.
  4. Git: point it at the bundle with git config --global http.sslCAInfo /path/to/ca-bundle.pem (or GIT_SSL_CAINFO). On Windows, git config --global http.sslBackend schannel makes Git use the Windows certificate store, where corporate roots usually already are (git-config).
  5. Node.js and npm: Node trusts its own bundled CA list, not the OS store. Add a root with NODE_EXTRA_CA_CERTS=/path/corp-root.pem (read once at start) or, on Node 23.8 and later, run with --use-system-ca. For npm alone: npm config set cafile /path/corp-root.pem.
  6. Do not disable verification with -k, git -c http.sslVerify=false or NODE_TLS_REJECT_UNAUTHORIZED=0. Node's own documentation calls the last one strongly discouraged: it turns off certificate validation for every connection the process makes.

How to confirm the fix

curl -sS -o /dev/null -w '%{http_code} verify=%{ssl_verify_result}\n' https://example.com/
# 200 verify=0
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | grep 'Verify return code'
# Verify return code: 0 (ok)

The SSL/TLS checker shows the chain your server sends and whether a standard client can build it to a trusted root, independent of your machine's trust store.

Related errors

CertificateExpiry, issuer, domains (SAN)
ChainIntermediate and root CA validation
TLS ProtocolTLS version and cipher suite
VulnerabilitiesHeartbleed, POODLE, weak ciphers

Why teams trust us

TLS 1.3
supported
Full
CA chain check
3,158
checks in 30 days
30/14/7
days-to-expiry alerts

How it works

1

Enter domain

2

TLS chain verified

3

Expiry date & vulnerabilities

What Does the SSL Check Cover?

SSL/TLS is the encryption protocol that protects data between the browser and server. Our tool analyzes the certificate, chain of trust, TLS version, and knownvulnerabilities.

Certificate Details

Issuer, validity period, signature algorithm, covered domains (SAN), and validation type (DV/OV/EV).

Chain of Trust

Full chain verification: from leaf certificate through intermediates to root CA.

TLS Analysis

Protocol version (TLS 1.2/1.3), cipher suites, Perfect Forward Secrecy (PFS) support.

Expiry Alerts

Set up a monitor — get Telegram and email alerts 30/14/7 days before expiration.

DV vs OV vs EV Certificates

DV (Domain Validation)
  • Confirms domain ownership only
  • Issued in minutes automatically
  • Free via Let's Encrypt
  • Suitable for most websites
  • Most common certificate type
OV / EV
  • Organization (OV) or Extended Validation (EV)
  • Issued in 1-5 business days
  • Costs $50 to $500/year
  • For finance, e-commerce, government sites
  • Increases user trust

Who uses this

DevOps

SSL certificate monitoring

Security

TLS config audit

SEO

HTTPS as ranking factor

E-commerce

customer trust

Common Mistakes

Expired certificateBrowsers block sites with expired SSL. Set up auto-renewal or monitoring.
Incomplete certificate chainWithout intermediate CA, some browsers and bots cannot verify the certificate.
Mixed content on HTTPS siteHTTP resources on an HTTPS page — the browser lock icon disappears, reducing trust.
Using TLS 1.0/1.1Legacy TLS versions have known vulnerabilities. Use TLS 1.2+ or 1.3.
Domain mismatch in certificateThe certificate must cover all site domains, including www and subdomains.

Best Practices

Set up auto-renewalLet's Encrypt + certbot with cron — certificate renews automatically every 60-90 days.
Enable HSTSStrict-Transport-Security header forces browsers to always use HTTPS.
Use TLS 1.3TLS 1.3 is faster (1-RTT handshake) and safer — legacy ciphers removed.
Monitor expiration datesCreate a monitor on Enterno.io — get notified well before expiration.
Verify chain after renewalAfter certificate renewal, confirm that intermediate certificates are installed.

Get more with a free account

SSL certificate monitoring, check history and alerts 30 days before expiry.

Sign up free

Learn more

Sources

Frequently Asked Questions

Why does the site work in the browser but curl says unable to get local issuer certificate?

Browsers can fetch a missing intermediate certificate on their own, while curl verifies only what the server sends against its CA bundle. The server is missing its intermediate certificate; serve the full chain.

Is this a problem with my computer or the server?

If every HTTPS site fails from that machine, the local CA bundle is missing or a proxy is re-signing traffic. If only one site fails everywhere, that server is not sending its intermediate certificate.

How do I fix unable to get local issuer certificate in Git on Windows?

Run git config --global http.sslBackend schannel so Git uses the Windows certificate store, which normally contains corporate root certificates. Alternatively set http.sslCAInfo to a PEM bundle that includes the root.

Is it safe to set NODE_TLS_REJECT_UNAUTHORIZED=0?

No. It disables certificate validation for every TLS connection in the process. Add the missing root with NODE_EXTRA_CA_CERTS instead.

What is the difference between error 20 and error 21?

Both mean the chain could not be completed. Error 20 says the issuer of the top certificate is not trusted locally; error 21 says only the leaf was available and nothing could be verified, which is how clients that keep verifying report a missing intermediate.

Try the live tool that powered this guide

Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.