How to Fix Git SSL Certificate Problem
The Git SSL certificate problem appears whenever Git tries to clone, fetch, or push over HTTPS and cannot verify the server's SSL/TLS certificate. The full message is usually fatal: unable to access 'https://...': SSL certificate problem: unable to get local issuer certificate, or for internal servers, SSL certificate problem: self signed certificate. Git aborts the operation because it cannot build a chain of trust from the server's certificate back to a root certificate authority (CA) that it knows about.
Unlike a web browser, Git does not always ship with its own trust store. On Linux it relies on the system CA bundle; on Windows it may use the OS certificate store (Schannel) or a bundled CA file depending on how it was installed. When that trust store is missing, outdated, or simply lacks the specific CA that signed the server's certificate, Git cannot verify the server and refuses the connection. The reassuring part is that almost every case maps to one of six root causes, and the fix is usually a single command. This guide walks through them in the order that resolves the most cases first.
Common Causes
Before diving into the step-by-step fixes, the table below summarizes the six root causes behind the Git SSL certificate problem, where each one originates, and the typical scenario in which you encounter it. Use it to narrow down which step applies to your situation.
| Root Cause | Where It Originates | Typical Scenario |
|---|---|---|
| Outdated CA certificate bundle | Client | The system ca-certificates package is older than the CA that signed the server cert. |
| Self-signed certificate | Server | An internal Git server uses a self-signed cert that no trust store knows. |
| Incorrect system date/time | Client | A wrong clock makes a valid certificate look expired or not yet valid. |
| Corporate proxy / MITM firewall | Network | A proxy re-signs HTTPS traffic with its own CA that Git does not trust. |
| Missing enterprise root CA | Client | The company CA has not been added to Git's CA bundle. |
| Incomplete certificate chain | Server | The server sends only the leaf certificate and omits the intermediate. |
Step 1: Check System Date and Time
The TLS trust model depends on comparing a certificate's validity dates against the current time. If your machine's clock is wrong — even by a few hours, or set to the wrong year — Git may treat a perfectly valid certificate as expired or "not yet valid" and report an SSL certificate problem. This is the cheapest cause to rule out, so start here.
Check the current time and make sure NTP synchronization is enabled. On Linux, use timedatectl; on macOS, sntp time.apple.com; on Windows, the w32tm command. If the displayed time is off, correct it and retry the Git command.
# Linux: check status and enable NTP sync
timedatectl
sudo timedatectl set-ntp true
# macOS: verify drift against Apple's time server
sntp time.apple.com
# Windows: force a resync with the configured time server
w32tm /resync
After correcting the clock, retry the failing git clone or git pull. If the error vanishes, an incorrect date was the only issue. This step also matters after a VM or container resumes from suspension, when the guest clock may have drifted significantly.
Step 2: Update CA Certificates (update-ca-certificates)
If your CA bundle is older than the CA that issued the server's certificate, Git has no way to trust it. This happens frequently after a public CA rotates its roots — for example, when the old DST Root CA X3 expired and Let's Encrypt moved to ISRG Root X1 and X2. Updating the system CA package refreshes the bundle with all recently-added root CAs.
On Debian, Ubuntu, and derivatives, install the ca-certificates package and run update-ca-certificates. On RHEL, CentOS, Fedora, and derivatives, the equivalent tool is update-ca-trust. On macOS, install the ca-certificates formula via Homebrew so Git's bundled curl can find a current bundle.
# Debian / Ubuntu
sudo apt update
sudo apt install -y ca-certificates
sudo update-ca-certificates
# RHEL / CentOS / Fedora
sudo dnf install -y ca-certificates
sudo update-ca-trust
# macOS (Homebrew)
brew install curl ca-certificates
If the output reports that new certificates were added, the missing root was almost certainly the culprit. Retry your Git operation. If it still fails, the next step is to point Git explicitly at the refreshed bundle.
Step 3: Configure Git http.sslCAInfo
Git's http.sslCAInfo setting points to the CA bundle file Git uses for verification. If it is unset and Git cannot auto-detect a bundle, or if it points to a stale or empty file, verification fails with "unable to get local issuer certificate". Check the current value first, then point it at the system bundle.
# Print the current CA bundle Git uses (may be empty)
git config --global http.sslCAInfo
# Point Git at the Debian/Ubuntu system bundle
git config --global http.sslCAInfo /etc/ssl/certs/ca-certificates.crt
# RHEL/Fedora uses a single consolidated bundle
git config --global http.sslCAInfo /etc/pki/tls/certs/ca-bundle.crt
To confirm Git is now receiving a complete, valid chain, inspect the certificate with openssl s_client. The command below prints every certificate in the chain; you should see at least the server (leaf) certificate and the intermediate that signs it.
# Connect and print the full certificate chain
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
# Show validity dates, issuer, subject, and SANs
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates -issuer -subject -ext subjectAltName
If the chain is complete and the bundle path is correct, Git should now verify successfully. On Windows, an alternative is to switch Git's SSL backend to schannel, which uses the OS trust store instead of a PEM file.
Step 4: Disable SSL Verification Temporarily
When you need to clone from a known internal server in a hurry, you can disable verification for a single command. This is a useful diagnostic — if the clone succeeds with verification off, you have confirmed the problem is purely a trust issue, not a network or authentication problem. However, you should never leave verification off permanently for public repositories, because it removes all protection against man-in-the-middle attacks.
# Disable for a single clone only (does not change global config)
git -c http.sslVerify=false clone https://example.com/repo.git
# Disable globally (NOT recommended; remove after testing)
git config --global http.sslVerify false
# Re-enable verification
git config --global --unset http.sslVerify
Prefer the -c form, which applies only to that one invocation and leaves your global config untouched. Once you have confirmed the cause is a trust problem, fix it properly with Step 6 (adding the certificate) rather than relying on disabled verification.
Step 5: Check Proxy Settings
Many corporate networks run a proxy or firewall that performs HTTPS inspection. It intercepts the TLS connection, re-signs the traffic with the company's own CA, and forwards it. Git does not trust that CA, so the handshake fails with an SSL certificate error that looks identical to a missing CA bundle. The clue is usually that the error only happens on the corporate network.
First, check whether proxy environment variables are set and whether Git is configured to use a proxy. Then, if HTTPS inspection is in place, obtain the corporate CA certificate and add it to the bundle using the method in Step 6.
# Inspect proxy-related environment variables
env | grep -i proxy
# Tell Git to use an HTTP(S) proxy
git config --global http.proxy http://proxy.corp.example.com:8080
git config --global https.proxy http://proxy.corp.example.com:8080
# Remove the proxy settings
git config --global --unset http.proxy
git config --global --unset https.proxy
If disabling the proxy makes Git work, the proxy or its CA is the cause. On Windows, also check the system proxy in Internet Options (run inetcpl.cpl) and the HTTP_PROXY/HTTPS_PROXY environment variables that many tools read.
Step 6: Fix Self-Signed Certificate Issues
Internal Git servers often use a self-signed certificate, or a certificate signed by an internal CA that no public trust store carries. The correct fix is to add that certificate to your system's CA bundle so Git trusts it — this keeps verification enabled and your traffic protected. Avoid disabling verification globally just to work around one internal server.
Export the server certificate with openssl, then install it as a trusted CA. On Debian/Ubuntu, place the PEM file in /usr/local/share/ca-certificates/ with a .crt extension and run update-ca-certificates; on RHEL/Fedora, copy it into /etc/pki/ca-trust/source/anchors/ and run update-ca-trust.
# Export the internal server's certificate
echo | openssl s_client -connect git.internal.example.com:443 \
-servername git.internal.example.com 2>/dev/null \
| openssl x509 -out git-server.crt
# Debian / Ubuntu — trust it system-wide
sudo cp git-server.crt /usr/local/share/ca-certificates/git-server.crt
sudo update-ca-certificates
# RHEL / Fedora — trust it system-wide
sudo cp git-server.crt /etc/pki/ca-trust/source/anchors/git-server.crt
sudo update-ca-trust extract
After installing the certificate, retry the Git operation with verification still enabled. If it succeeds, you have fixed the root cause rather than masking it. On Windows, the cleanest equivalent is to add the certificate to the "Trusted Root Certification Authorities" store, which Git's schannel backend will then use automatically.
Git SSL Configuration Commands
The block below consolidates the most useful Git and OpenSSL commands for diagnosing and fixing SSL certificate problems. Keep it handy when the exact step is not yet clear.
# View all SSL-related Git configuration
git config --global --get-regexp ssl
# Set the CA bundle Git uses for verification
git config --global http.sslCAInfo /etc/ssl/certs/ca-certificates.crt
# Windows: use the OS trust store instead of a PEM file
git config --global http.sslBackend schannel
# Disable verification for one clone (test only)
git -c http.sslVerify=false clone https://example.com/repo.git
# Inspect the certificate chain the server presents
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
# Print validity dates, issuer, subject, and SANs
echo | openssl s_client -connect example.com:443 2>/dev/null \
| openssl x509 -noout -dates -issuer -subject -ext subjectAltName
# Count how many certificates the server sends (chain completeness)
echo | openssl s_client -connect example.com:443 -showcerts 2>/dev/null \
| grep -c "BEGIN CERTIFICATE"
Quick Reference: Causes and Fixes
| Symptom / Clue | Root Cause | Fix |
|---|---|---|
| "unable to get local issuer certificate" | Missing or outdated CA bundle | Update CAs (Step 2); set http.sslCAInfo (Step 3) |
| "self signed certificate" | Internal server cert not trusted | Add the cert to the bundle (Step 6) |
| Works on other machines, fails on one | Wrong clock or stale CA | Check time (Step 1); update CAs (Step 2) |
| Only fails on the corporate network | Proxy / MITM firewall | Configure proxy + add its CA (Step 5) |
| Error after a cert renewal | New issuing CA not in bundle | Update CAs (Step 2) |
| Need to clone once, quickly | Trust not yet configured | Temporary disable for one command (Step 4) |
Frequently Asked Questions
What does "SSL certificate problem: unable to get local issuer certificate" mean?
It means Git received the server's certificate but could not find the issuing certificate authority (the "issuer") in its trusted CA bundle, so it could not build a chain of trust. This is almost always caused by an outdated CA bundle, a missing intermediate certificate on the server, or a corporate proxy that re-signs traffic. Update your CA certificates and point http.sslCAInfo at the refreshed bundle; if it persists, inspect the chain with openssl s_client -showcerts.
Is it safe to set http.sslVerify to false?
Only as a temporary diagnostic, and only for a single command using git -c http.sslVerify=false clone .... Setting it globally disables certificate verification for every HTTPS Git operation, which means a man-in-the-middle attacker could intercept your credentials and repository contents without you knowing. Always prefer adding the correct certificate (Step 6) over disabling verification.
How do I fix the Git SSL certificate problem on Windows?
The easiest Windows fix is to switch Git's SSL backend to the OS trust store: git config --global http.sslBackend schannel. Git will then use the Windows certificate store, which you can manage with certmgr.msc. If you prefer the OpenSSL backend, download a current cacert.pem from the curl project and point http.sslCAInfo at it. For internal servers, add the certificate to "Trusted Root Certification Authorities" so Schannel trusts it automatically.
Why does Git fail in a terminal but the same URL works in a browser?
Browsers maintain their own, frequently-updated trust store and often auto-download missing intermediates, whereas Git relies on the system CA bundle or a bundled PEM file that may be older or incomplete. A browser may also be configured to use a different proxy path. The fix is the same: update the CA certificates, point http.sslCAInfo at the correct bundle, and confirm the chain with openssl s_client. If a corporate proxy is involved, add the proxy's CA to the bundle as well.
Conclusion
The Git SSL certificate problem looks alarming, but it always boils down to one question: can Git find a trusted path from the server's certificate back to a root CA it knows? Work through the six fixes in order: correct the system clock, update the CA certificates, point http.sslCAInfo at the right bundle, verify the chain with openssl s_client, check for a corporate proxy, and add any self-signed or internal certificates to the trust store. The vast majority of cases are resolved by Steps 1 through 3.
Once Git connects, keep the CA bundle current with regular system updates, avoid leaving http.sslVerify disabled, and treat internal server certificates as configuration that should be installed once and trusted going forward. A little proactive maintenance keeps your clones, fetches, and pushes working securely over HTTPS.