- git on Windows
- Exact text checked with the real tool
schannel: SEC_E_UNTRUSTED_ROOT (0x80090325)
Also seen in: curl.exe on Windows, Git for Windows, Visual Studio, other programs that use Schannel
In one sentence
Windows could not link the Git server's certificate to a root in its trust store: usually a company or proxy root that is not installed, or a self-signed server.
Where you see it
In Git for Windows when it uses the Windows TLS library, Schannel (the installer option “Use the native Windows Secure Channel library”, or http.sslBackend=schannel):
$ git clone https://git.example.com/team/app.git
Cloning into 'app'...
fatal: unable to access 'https://git.example.com/team/app.git/': schannel: SEC_E_UNTRUSTED_ROOT (0x80090325) - The certificate chain was issued by an authority that is not trusted.
The curl.exe that ships with Windows prints the same text as curl: (60) schannel: SEC_E_UNTRUSTED_ROOT (0x80090325) - …. Versions of curl before 7.73.0, and the git versions built on them, printed schannel: next InitializeSecurityContext failed: SEC_E_UNTRUSTED_ROOT (0x80090325) - … (curl’s schannel.c). Microsoft lists SEC_E_UNTRUSTED_ROOT (0x80090325) as “The certificate chain was issued by an authority that is not trusted” (Windows error codes).
Check which TLS library your git uses:
git config --show-origin --get-all http.sslBackend
What it means
With Schannel, git lets Windows check the server’s certificate. Windows builds the certificate chain up to a root certificate in its Trusted Root Certification Authorities store. Here the chain ends at a root that this machine does not trust, or Windows could not reach any root. A browser on the same machine may still open the site, because Chrome, Edge and Firefox bring their own lists of trusted public roots in addition to the roots added to Windows.
Likely causes
The company’s root CA is not in the Windows store
Self-hosted Git servers often use a certificate from a company CA. Confirm which root the server’s chain ends at:
openssl s_client -connect git.example.com:443 -servername git.example.com -showcerts </dev/null 2>/dev/null | grep -E '^ [0-9]+ s:|^ i:'
Then look for that root under Trusted Root Certification Authorities in certmgr.msc (your account) or certlm.msc (the computer).
Fix: ask IT to deploy the root through Group Policy or Intune, or import it yourself:
# For your own account (no administrator rights; Windows asks you to confirm)
Import-Certificate -FilePath .\corp-root.cer -CertStoreLocation Cert:\CurrentUser\Root
# For the whole computer (administrator)
Import-Certificate -FilePath .\corp-root.cer -CertStoreLocation Cert:\LocalMachine\Root
Check the root’s fingerprint with IT before you import it. See How to trust a private root CA on Windows.
A TLS-inspection proxy re-signs your traffic
If public sites such as github.com fail too, a TLS-inspection proxy or an antivirus product is probably re-signing traffic with its own root. The -showcerts output above then shows the proxy’s name as the issuer. Fix: the proxy’s root must be in the Windows store, as above. See How to work behind a TLS-inspecting corporate proxy, safely.
The server uses a self-signed certificate
If the server’s certificate is its own issuer (the s: and i: lines are the same), there is no CA to trust. Fix: give the server a certificate from your company CA. As a stopgap for one server, you can trust exactly that CA certificate, and only for that host, with git’s OpenSSL backend:
git config --global http.sslBackend openssl
git config --global http.https://git.example.com/.sslCAInfo C:/certs/git-example-ca.pem
Note that with openssl, git no longer uses the Windows store: it uses its own CA bundle, and for this one host only the file you configure. With Schannel, http.schannelUseSSLCAInfo makes git use http.sslCAInfo instead of the Windows store (git-config).
Windows cannot reach the missing pieces
Windows downloads missing intermediates and trusted public roots when it needs them. On build agents and servers without internet access, that fails, and even a public root can be missing. Fix: make the server send its full chain (How to build the full chain file your server needs), and let IT distribute roots to disconnected machines (Microsoft guidance). certutil -verifyctl AuthRoot | findstr /i "lastsynctime" shows when Windows last updated its root list.
Check yours
Paste the certificates from openssl s_client -showcerts. The checker shows which root the chain needs, and flags root names of known HTTPS-inspection products.
Learn why
- Who do we trust? CAs, trust stores and self-signed certificates: why git, browsers and other tools can trust different roots.
- Certificate chains and path validation.
- The same problem with git’s OpenSSL backend: unable to get local issuer certificate.
Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.