एरर समाधान · डेवलपर एरर

curl Error 60: SSL Certificate Problem (Unable to Get Local Issuer)

Fix curl error 60 "SSL certificate problem: unable to get local issuer certificate" by finding whether the server chain, CA bundle, proxy or clock is at fault.

Error messagecurl: (60) SSL certificate problem: unable to get local issuer certificate

लेखक: SiteDownCheck संपादकीय टीम · अपडेट: अक्टूबर 5, 2026 · 5 मिनट पढ़ने में

curl error 60 means curl connected to the server over TLS but could not verify the server's certificate against the trusted certificate authorities (CAs) on your machine, so it aborted before sending your request. Browsers, curl and libraries such as Python requests, PHP and Git all perform this check, and they report it in different words.

You see it when running curl https://..., in PHP's cURL extension as cURL error 60, in WordPress HTTP API failures, in Git as "SSL certificate problem", and in CI jobs and Docker builds. The text after "SSL certificate problem:" names the actual reason:

curl: (60) SSL certificate problem: unable to get local issuer certificate
curl: (60) SSL certificate problem: certificate has expired
curl: (60) SSL certificate problem: self-signed certificate
curl: (60) SSL certificate problem: self-signed certificate in certificate chain
curl: (60) SSL: no alternative certificate subject name matches target host name 'example.com'

Decide whose side is broken

The central question is whether the server is misconfigured (everyone is affected) or your machine is (only you). Test the same URL from another machine, or use the SSL Checker और SSL Chain Debugger, which report chain problems from outside. A browser that loads the site fine does not prove the server is right, because browsers fetch missing intermediates themselves and curl does not.

Causes, most likely first

  1. The server sends an incomplete chain. It presents only its own certificate, not the intermediate CA certificate. This is the classic cause of "unable to get local issuer certificate" and the server owner must fix it.
  2. Your CA bundle is old or missing, common on minimal containers, old OS versions and embedded systems.
  3. A corporate proxy or antivirus intercepts TLS and re-signs traffic with a private CA that curl does not trust.
  4. The certificate expired (or is not valid yet because your system clock is wrong).
  5. A self-signed or private-CA certificate on an internal service.
  6. Hostname mismatch, where the name you use is not in the certificate's subject alternative names.

Step 1: see what the server presents

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null | grep -E "^ *[0-9]+ s:|^ *i:|Verify return code"

Reading the output:

  • Only one certificate shown (depth 0) with Verify return code: 21 (unable to verify the first certificate) means the chain is incomplete. That is a server problem.
  • Verify return code: 20 (unable to get local issuer certificate) can be either server or your trust store; test from a second machine.
  • 10 (certificate has expired) is exactly that; check dates with openssl x509 -noout -dates.
  • 18 or 19 indicates self-signed.

Fix when you own the server: serve the full chain

Use the full chain file from your CA, not only the leaf certificate. With Let's Encrypt, that is fullchain.pem:

ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
SSLCertificateFile    /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

Older Apache versions use a separate SSLCertificateChainFile for the intermediates. After reloading, re-run the openssl test and the SSL Chain Debugger. If the certificate expired, renew it; see how to renew an SSL certificate and automate it और Let's Encrypt renewal failures.

Fix when your machine is at fault

Update the CA bundle.

# Debian, Ubuntu
sudo apt-get update && sudo apt-get install --reinstall ca-certificates && sudo update-ca-certificates
# RHEL, Rocky, Fedora
sudo dnf reinstall ca-certificates && sudo update-ca-trust
# Alpine (Docker)
apk add --no-cache ca-certificates && update-ca-certificates

In Docker images, install ca-certificates in the Dockerfile. If the machine is very old, the root certificates it trusts may have expired; Let's Encrypt's 2021 root change broke older OpenSSL 1.0.x systems this way, so upgrade the OS or library.

Check the clock. A wrong date makes valid certificates look expired or not yet valid: date -u and timedatectl.

Corporate or antivirus interception. Get the company root CA certificate from IT and add it to the system store (copy to /usr/local/share/ca-certificates/ and run update-ca-certificates), or point curl at it with --cacert. Many Git, Node and Python tools use their own bundle variables, such as SSL_CERT_FILE, REQUESTS_CA_BUNDLE or NODE_EXTRA_CA_CERTS.

Internal CA or self-signed certificate.

curl --cacert /path/to/internal-ca.pem https://intranet.example.local/

Specify a bundle explicitly for testing: curl --cacert /etc/ssl/certs/ca-certificates.crt https://example.com/. For PHP, set curl.cainfo and openssl.cafile in php.ini.

Hostname mismatch

If the message mentions a subject name, compare the names the certificate covers with the host you request:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -ext subjectAltName

Fix by requesting a covered name, or by issuing a certificate that includes the one you need.

How to verify

Run curl -sS -o /dev/null -w "%{http_code} verify=%{ssl_verify_result}\n" https://example.com/ and expect 200 verify=0. Confirm from outside with the SSL Checker, and check TLS versions with the TLS वर्शन चेकर if an old client still fails. Add an SSL expiry alert so certificates do not lapse again.

अगले कदम

सामान्य प्रश्न

Why does the site open in my browser but fail in curl?

Browsers can download a missing intermediate certificate on their own, while curl uses only what the server sends plus your local CA bundle. A chain that works in a browser but fails in curl is an incomplete chain.

Is using curl -k acceptable?

Only for a quick local test. It removes protection against man-in-the-middle attacks, so do not use it in production scripts.

Does error 60 mean the certificate is expired?

Not necessarily. The text after the colon tells you: "unable to get local issuer certificate", "certificate has expired", or "self-signed certificate" each point to a different fix.

The same command works on another server. Why?

That server has a newer CA bundle, a correct clock or no interception proxy. Compare openssl version, date and the CA bundle between the machines.

Get notified when this fix updates

Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.

यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.