This error appears in curl, Git, pip, wget, and other command-line tools that use OpenSSL for TLS verification. It is not a browser error. The message means the tool verified the server presented a valid-looking certificate, but when it tried to walk the certificate chain up to a trusted root, it could not find the issuing Certificate Authority in its local CA bundle.

‘Local issuer’ refers to the certificate trust store on your machine that the tool is checking against. The chain walk failed because the intermediate or root CA is not in that store. The fix is to add the missing CA to the store, or to point the tool at a bundle that already contains it. Disabling verification, which many guides recommend as a first step, is the wrong answer for anything running in production.

 

Do Not Use – insecure as a Fix

The tempting one-liner is curl -k or curl –insecure, or git config –global http.sslVerify false. These disable certificate verification entirely, making the connection vulnerable to man-in-the-middle attacks. An attacker on the network can intercept the connection, present any certificate, and the tool will accept it silently.

These flags exist for debugging and for local development environments where you fully control the network. Using them in production scripts, CI/CD pipelines, Dockerfiles, or anywhere data flows in both directions is a significant security risk that is routinely exploited in supply chain attacks.

Setting http.sslVerify false globally in Git is particularly dangerous. It applies to every repository operation, including pulls from package registries, submodules, and any Git remote. This setting has been the entry point for multiple supply chain compromises where attackers positioned themselves on the network to inject malicious code into what appeared to be legitimate pull operations.

 

What the Error Actually Means

When curl or Git makes an HTTPS connection, it receives the server’s certificate (and hopefully the intermediate certificates in the chain). It then verifies this chain against a local CA bundle: a file containing the root certificates of trusted Certificate Authorities. The bundle is typically located at /etc/ssl/certs/ca-certificates.crt on Debian/Ubuntu, /etc/pki/tls/certs/ca-bundle.crt on RHEL/CentOS/Fedora, or at the path specified by the CURL_CA_BUNDLE or SSL_CERT_FILE environment variables.

The error fires when the chain walk reaches a certificate whose issuer is not in the local bundle. This can happen at the intermediate CA level (the intermediate is not in the bundle) or at the root level (the root is not in the bundle). In corporate environments with SSL inspection, it fires because the proxy is substituting its own certificate issued by a corporate CA that is not in the standard bundle.

 

Diagnose the Cause First

# See exactly what certificate the server is presenting and where the chain breaks:

$ curl -v https://affected-server.com 2>&1 | grep -A5 ‘SSL certificate’

 

# Get the full certificate chain details:

$ openssl s_client -connect affected-server.com:443 -showcerts 2>/dev/null

# Look for: ‘Verify return code: 20 (unable to get local issuer certificate)’

# and the chain depth where verification fails.

 

# Check which CA bundle curl is using:

$ curl –version | grep CAfile

# Or:

$ curl -v https://affected-server.com 2>&1 | grep ‘CAfile’

 

Fix 1: Update the System CA Bundle

On Linux systems, the ca-certificates package contains the system CA bundle. If it is outdated, newer root certificates (or CAs that have been cross-signed) may be missing. This is the first thing to try on a machine that connects to public internet endpoints.

# Debian / Ubuntu:

sudo apt-get update && sudo apt-get install -y ca-certificates

sudo update-ca-certificates

 

# RHEL / CentOS / Fedora:

sudo yum update ca-certificates

# or:

sudo dnf update ca-certificates

 

# Alpine Linux (common in containers):

apk add –no-cache ca-certificates

 

# macOS (update the system trust store):

# Install updates via System Preferences > Software Update

# Or for Homebrew-dependent tools:

brew install ca-certificates

 

Fix 2: Add a Corporate or Custom CA to the System Bundle

For corporate environments where a proxy performs SSL inspection, or for internal servers using a private CA, the CA certificate needs to be added to the system trust store. Obtain the CA certificate in PEM format from your IT team or from the server’s certificate chain.

# Debian / Ubuntu: copy the .crt file to the extra certs directory and update:

sudo cp corporate-ca.crt /usr/local/share/ca-certificates/

sudo update-ca-certificates

# Output should confirm: ‘1 added’ (or however many certs you added)

 

# RHEL / CentOS / Fedora: copy to the anchors directory and update:

sudo cp corporate-ca.crt /etc/pki/ca-trust/source/anchors/

sudo update-ca-trust

 

# Verify the cert was added:

$ openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt corporate-ca.crt

# Should return: corporate-ca.crt: OK

 

# To export a corporate CA from Windows (if you’re on a domain-joined machine):

# certlm.msc > Trusted Root Certification Authorities > export as Base-64 .cer

# Rename .cer to .crt for Linux

 

Fix 3: Configure the CA Bundle Per Tool

If you cannot or prefer not to modify the system bundle, each tool can be pointed at a specific CA bundle file.

 

curl

# One-off: specify the CA bundle for a single request:

curl –cacert /path/to/your-bundle.crt https://server.example.com

 

# Persistent: set the environment variable (add to .bashrc or .profile):

export CURL_CA_BUNDLE=/path/to/your-bundle.crt

 

# Or in the curl config file (~/.curlrc):

# cacert = /path/to/your-bundle.crt

 

Git

# For a single repository:

git config http.sslCAInfo /path/to/your-bundle.crt

 

# Globally for all repositories (this user only):

git config –global http.sslCAInfo /path/to/your-bundle.crt

 

# For a specific host only:

git config –global http.https://internal.company.com.sslCAInfo /path/to/ca.crt

 

# On Windows, you may also need to tell Git to use the Windows cert store:

git config –global http.schannelCheckRevoke false

git config –global http.sslBackend schannel

 

pip (Python)

# One-off: specify the CA bundle for a single install:

pip install somepackage –cert /path/to/your-bundle.crt

 

# Persistent: set in pip configuration:

pip config set global.cert /path/to/your-bundle.crt

 

# Or via environment variable:

export REQUESTS_CA_BUNDLE=/path/to/your-bundle.crt

export SSL_CERT_FILE=/path/to/your-bundle.crt

 

# Python’s requests library reads REQUESTS_CA_BUNDLE automatically.

 

Fix 4: Containers and CI Environments

Minimal container images (Alpine, minimal Ubuntu/Debian images) often ship without ca-certificates installed. This is the most common cause of this error in CI/CD pipelines. The fix is to install ca-certificates as part of the container build, or as an early step in the pipeline.

# In a Dockerfile (Alpine):

RUN apk add –no-cache ca-certificates

 

# In a Dockerfile (Debian/Ubuntu minimal):

RUN apt-get update && apt-get install -y –no-install-recommends ca-certificates \

&& rm -rf /var/lib/apt/lists/*

 

# Adding a custom CA to a container image (for corporate environments):

COPY corporate-ca.crt /usr/local/share/ca-certificates/

RUN update-ca-certificates

 

# In a GitHub Actions workflow (if using a runner without the cert):

# – name: Trust corporate CA

#   run: |

#     echo ‘${{ secrets.CORP_CA_CERT }}’ > /tmp/corp-ca.crt

#     sudo cp /tmp/corp-ca.crt /usr/local/share/ca-certificates/

#     sudo update-ca-certificates

 

Quick Reference: Situation to Fix

 

Situation Root cause Fix
Public internet server, old Linux machine Outdated ca-certificates package apt/yum update ca-certificates
Corporate network with SSL inspection proxy Proxy CA not in bundle Add corporate CA .crt to system bundle; update-ca-certificates
Internal server with private CA Private CA not in bundle Add private CA .crt to system bundle; update-ca-certificates
Alpine / minimal container image ca-certificates package not installed apk add ca-certificates in Dockerfile
CI pipeline on any runner Bundle outdated or incomplete Install ca-certificates as pipeline setup step
One machine only, all tools affected System bundle corrupted or wrong path Reinstall ca-certificates; check CURL_CA_BUNDLE / SSL_CERT_FILE env vars
Only one tool (e.g. Git only) Tool not using system bundle Configure tool-specific sslCAInfo / –cacert / –cert pointing to correct bundle

 

Frequently Asked Questions

 

The same URL works in Chrome but fails in curl. Why?

Chrome uses the operating system’s trust store (Windows Certificate Store or macOS Keychain) and typically includes a broader, more frequently updated set of root certificates. curl on Linux uses its own CA bundle file, which is updated separately via the ca-certificates package. The two stores can diverge, particularly on machines that have not received operating system updates recently. The fix is to update the ca-certificates package on the Linux system, or to identify which CA is trusted by Chrome but missing from the Linux bundle and add it explicitly.

 

This started happening after a server certificate renewal. Why?

Certificate renewals sometimes switch to a different intermediate CA, either because the CA reorganized its intermediate chain or because a new certificate type was chosen. If the new intermediate CA is not in your system’s bundle but the old one was, the error appears after renewal even though the renewal was otherwise successful. Run openssl s_client -connect server:443 -showcerts to see the full chain the server is presenting. Identify the intermediate CA and verify it is in your local bundle. If it is not, adding it or updating the ca-certificates package resolves the issue.

 

How do I create a CA bundle that includes my corporate CA plus the standard roots?

Concatenate your corporate CA certificate with the system’s existing CA bundle: cat /etc/ssl/certs/ca-certificates.crt corporate-ca.crt > combined-bundle.crt. Point your tool at combined-bundle.crt using the appropriate flag (–cacert for curl, http.sslCAInfo for Git, –cert for pip). This avoids replacing the system bundle while still adding the trust you need.

 

Tag :

Previous Post
Next Post