Setup & configAlways fixable

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 certificate
fatal: unable to access '<url>': SSL certificate problem: self signed certificate in certificate chain
schannel: failed to receive handshake, SSL/TLS connection failed

You’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.

quick fix
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

  1. 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 1
    openssl 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"
    
  2. 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)
    
  3. 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 3
    cp "$(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.pem
    
    Show 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"
    
  4. 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 4
    git config --global http.sslBackend schannel
    

    This is the cleanest fix on a managed Windows laptop. With schannel, http.sslCAInfo is ignored.

  5. 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 5
    git 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 false
    
  6. Or 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 6
    git 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 config

Read and write Git settings for one repo, your user, or the whole machine.

git clone

Copy a remote repository, its full history and its branches, onto your machine.

git remote

Manage the named URLs your repository syncs with.

git fetch

Download new commits from the remote without changing any of your files.

git credential / credential.helper

Stop 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

← All Git Rescue guides