Fix 'SSL certificate problem: unable to get local issuer certificate'
Git says 'SSL certificate problem: unable to get local issuer certificate' — how do I fix it?
If you’re seeing this error
fatal: unable to access '<url>': SSL certificate problem: unable to get local issuer certificatefatal: unable to access '<url>': SSL certificate problem: self signed certificate in certificate chainschannel: failed to receive handshake, SSL/TLS connection failedYou’re in the right place — the fix is below.
Short answer
Something is intercepting your HTTPS traffic — nearly always a corporate inspection proxy such as Zscaler or Netskope — and Git does not trust the certificate it presents. The correct fix is to add your organisation's root CA to the bundle Git reads, via http.sslCAInfo. Do not turn verification off: sslVerify=false makes every push and pull interceptable by anyone.
git config --global http.sslCAInfo /path/to/company-ca-bundle.pem
Point Git at a bundle that includes your organisation's root certificate
Does this match your situation?
- 'SSL certificate problem: unable to get local issuer certificate'
- 'self signed certificate in certificate chain'
- It works at home and fails on the office network or the VPN.
- A browser opens the same URL without complaint.
- npm, pip and curl are failing in the same way at the same time.
Step-by-step fix
Confirm what is actually presenting the certificate
If the issuer is your employer rather than a public authority, TLS inspection is in play and the diagnosis is finished. This is also how you tell an inspection proxy from a genuinely misconfigured server.
step 1openssl s_client -showcerts -connect github.com:443 </dev/null 2>/dev/null | grep -E 'issuer|subject'Show the Windows / PowerShell version
Windows / PowerShell(Invoke-WebRequest -Uri https://github.com -UseBasicParsing).BaseResponse | Out-Null [Net.ServicePointManager]::ServerCertificateValidationCallback = $null curl.exe -v https://github.com 2>&1 | Select-String "issuer|subject"Get the root certificate
Your IT team can supply it, and every browser will export it: open the site, inspect the certificate, and save the topmost item in the chain as Base-64 encoded PEM. That single file is what Git is missing.
step 2# Chrome/Edge: padlock -> Connection is secure -> Certificate # -> Details -> select the ROOT entry -> Export as Base-64 (.cer/.pem)Append it to the full bundle — do not replace it
Pointing http.sslCAInfo at a file containing only your corporate root breaks every public host, because the public authorities are no longer trusted. Copy Git's own bundle and add yours to the end of it.
step 3cp "$(git config --get http.sslCAInfo || echo /etc/ssl/certs/ca-certificates.crt)" ~/git-ca-bundle.pem cat company-root.pem >> ~/git-ca-bundle.pem git config --global http.sslCAInfo ~/git-ca-bundle.pemShow the Windows / Git for Windows version
Windows / Git for Windows$bundle = "C:/Program Files/Git/mingw64/etc/ssl/certs/ca-bundle.crt" Copy-Item $bundle "$HOME/git-ca-bundle.pem" Get-Content company-root.pem | Add-Content "$HOME/git-ca-bundle.pem" git config --global http.sslCAInfo "$HOME/git-ca-bundle.pem"On Windows, let Git use the OS certificate store instead
Corporate machines already have the root installed in Windows for the browser's benefit. Switching Git's TLS backend to schannel makes it read that same store, which usually removes the problem without handling any files at all.
step 4git config --global http.sslBackend schannelThis is the cleanest fix on a managed Windows laptop. With schannel, http.sslCAInfo is ignored.
Scope an exception to one host if you must
For a single internal server with a self-signed certificate, a per-host setting is far safer than a global one — everything else keeps full verification.
step 5git config --global http."https://git.internal.company.com/".sslCAInfo /path/to/internal-ca.pem # absolute last resort, one host only, never globally: git config --global http."https://git.internal.company.com/".sslVerify falseOr sidestep TLS entirely with SSH
SSH does not use the certificate chain at all, so an inspection proxy that rewrites HTTPS has nothing to rewrite. Where port 22 is open, switching the remote is often the fastest route to working again.
step 6git remote set-url origin git@github.com:user/repo.git ssh -T git@github.com
Why this works
TLS verification works by chaining the certificate a server presents up to a root your machine already trusts. An inspection proxy deliberately breaks that chain: it terminates the connection, reads it, and re-encrypts using its own certificate, so the root at the top is your employer's rather than a public authority's. Browsers accept this because the corporate root was installed into the operating system store by IT. Git on Linux and macOS does not read that store — it carries its own PEM bundle — so it sees a chain ending in an unknown issuer and refuses. That is why the browser works and Git does not, and it is also why sslVerify=false is the wrong answer: it does not add trust, it stops checking, leaving your credentials and code exposed to anyone able to sit in the middle.
If that didn’t work
- Set GIT_CURL_VERBOSE=1 and read which certificate file Git actually opened.
- http.sslCAPath (a directory of hashed certificates) is used by some distributions instead of sslCAInfo.
- npm, pip and AWS tooling each keep their own CA bundle — expect to repeat this for them.
- Ask your network team to exclude your Git host from TLS inspection; many will for developer traffic.
How to stop it happening again
- Keep one merged CA bundle in your dotfiles so a new machine takes minutes rather than an afternoon.
- Prefer http.sslBackend schannel on managed Windows machines so the OS store stays the single source of truth.
- Never commit sslVerify=false into a shared script or Dockerfile — it silently disables verification for everyone.
- Use SSH remotes on networks that inspect HTTPS.
Commands used in this guide
git configRead and write Git settings for one repo, your user, or the whole machine.
git cloneCopy a remote repository, its full history and its branches, onto your machine.
git remoteManage the named URLs your repository syncs with.
git fetchDownload new commits from the remote without changing any of your files.
git credential / credential.helperStop Git asking for your username and password on every push.
Still stuck?
Search the full command reference and every other rescue guide — there are 76 of them, covering everything from detached HEAD to force-push disasters.
Browse all guides →Frequently asked questions
What causes 'SSL certificate problem: unable to get local issuer certificate' in Git?
Git could not chain the certificate it was given up to a root it trusts. On a corporate network this is almost always a TLS inspection proxy such as Zscaler or Netskope presenting its own certificate, whose root is in the OS store your browser reads but not in the PEM bundle Git carries.
Should I use git config http.sslVerify false?
No — not globally. It does not add trust, it stops checking, so anything on the network path can read and alter your traffic, including the credentials you push with. If you truly must, scope it to a single host and treat it as temporary.
Why does my browser work but Git fails on the same URL?
The browser reads the operating system's certificate store, where your organisation's root was installed by IT. Git on Linux and macOS uses its own bundled PEM file instead, which knows nothing about that root. On Windows, http.sslBackend schannel makes Git read the OS store as well.
How do I add a corporate certificate to Git?
Copy Git's existing CA bundle, append your organisation's root PEM to the end of the copy, and point http.sslCAInfo at it. Appending matters: a file containing only the corporate root breaks every public host, because the public authorities are no longer listed.
Does switching to SSH avoid this?
Yes. SSH authenticates with host keys rather than an X.509 chain, so an HTTPS inspection proxy has nothing to intercept. Change the remote with git remote set-url origin git@host:user/repo.git, assuming outbound port 22 is permitted.
Related rescue guides
Cloning or pushing dies with 'RPC failed' or 'the remote end hung up unexpectedly' — how do I get it through?
The connection dropped part-way through a large transfer. Nothing is damaged. Clone shallow to make the transfer small enough to finish (git clone --depth 1), then deepen it with git fetch --unshallow. Switching the remote to SSH avoids the HTTP layer entirely and fixes most stubborn cases.
Read the fix →Always fixableGit keeps saying authentication failed even though my password is correct — why?
GitHub stopped accepting account passwords over HTTPS in August 2021. You need a personal access token in place of the password, or better, switch the remote to SSH. If it worked yesterday, a cached old credential is usually the culprit — clear it and re-authenticate.
Read the fix →Always fixablegit clone or push fails with Permission denied (publickey) — how do I fix my SSH key?
The server didn't accept any key your SSH client offered. Either you have no key, the key isn't loaded into the agent, or its public half was never added to your account. Run ssh -T git@github.com to see exactly which keys are being tried.
Read the fix →Always fixableHow do I make Git remember my credentials?
Configure a credential helper that stores the token in your OS keychain, or switch to SSH keys and skip credentials entirely. Avoid the `store` helper — it writes your token to a plaintext file.
Read the fix →