Overview & Root Cause Summary: The error
fatal: unable to access '<repository_url>': SSL certificate problem: self-signed certificate in certificate chainoccurs when Git attempts to communicate with a remote server over HTTPS but cannot validate the SSL/TLS certificate against its trusted Certificate Authority (CA) bundle. This frequently happens in corporate networks employing SSL-inspecting proxy firewalls (such as Zscaler, Netskope, or Fortinet), custom internal Git servers with private CAs, or when Git is configured to use an isolated CA bundle instead of the operating system’s native trust store.
Understanding the Root Causes
- Corporate SSL Decryption & Inspection: Enterprise security gateways intercept outbound HTTPS traffic, resigning certificates on the fly using a company-specific internal Root CA that Git’s bundled OpenSSL certificate store does not recognize.
- Internal / Private Git Server: Self-hosted GitLab, GitHub Enterprise, or Bitbucket instances signed by an in-house private Certificate Authority.
- Platform CA Store Mismatch: Git on Windows or macOS defaulting to an isolated OpenSSL
ca-bundle.crtfile rather than querying the OS-level certificate keychain (Windows SChannel or Apple Keychain). - Outdated Local CA Bundle: Expired root certificates in the local Git installation preventing standard certificate chain verification.
Step 1: Quick Fix (Configure Git to Use the Native OS Trust Store)
Instead of relying on Git’s isolated OpenSSL bundle, configure Git to use your operating system’s built-in certificate store, which already trusts your organization’s internal Root CA.
# On Windows (Switch from OpenSSL to Windows Secure Channel / SChannel):
git config --global http.sslBackend schannel
# On macOS (Ensure Git uses Secure Transport / Keychain):
# If using Homebrew Git, export the system keychain certificates or configure the backend:
git config --global http.sslBackend secure-transport
# Test connectivity immediately:
git ls-remote
Step 2: Adding Corporate CA Bundle to Git (Cross-Platform)
If you are on Linux or prefer to maintain explicit certificate paths, provide your organization’s custom root CA certificate directly to Git.
# 1. Obtain your corporate Root CA (.pem or .crt file) and save it locally:
# Example path: /etc/ssl/certs/corporate-ca.crt or ~/.certs/corporate-ca.crt
# 2. Tell Git to use your custom CA bundle globally:
git config --global http.sslCAInfo /absolute/path/to/corporate-ca.crt
# 3. (Alternative) Append the enterprise CA to Git's default bundle:
cat /path/to/corporate-ca.crt >> $(git config --get http.sslCAInfo || echo "/etc/ssl/certs/ca-certificates.crt")
Step 3: Alternative Approach (Switch to SSH Protocol)
SSH authentication bypasses HTTPS inspection proxies entirely, making it immune to SSL certificate interception issues.
# 1. Generate an Ed25519 SSH key (if not already created):
ssh-keygen -t ed25519 -C "developer@example.com"
# 2. Copy your public key and add it to GitHub/GitLab settings:
cat ~/.ssh/id_ed25519.pub
# 3. Change your repository remote URL from HTTPS to SSH:
git remote set-url origin git@github.com:username/repository.git
# 4. Verify SSH connection:
ssh -T git@github.com
Verification & Testing Steps
Confirm that Git commands can successfully negotiate secure handshakes with the remote repository without SSL warnings.
# 1. Verify active SSL configuration settings:
git config --get-all http.sslBackend
git config --get-all http.sslCAInfo
# 2. Test querying remote repository references:
git ls-remote -h origin
# 3. Execute a standard fetch to confirm seamless data transfer:
git fetch origin
Summary Comparison Table
| Remediation Method | Security Level | Maintenance Overhead | Recommended Environment |
|---|---|---|---|
Native OS Store (http.sslBackend schannel) |
High (Full Verification) | None (Automated via OS) | Windows & macOS Corporate PCs |
Custom CA Bundle (http.sslCAInfo) |
High (Full Verification) | Low (Requires path setup) | Linux & CI/CD Docker runners |
| Switch to SSH Protocol | Highest (Cryptographic Keys) | One-time Key Generation | All platforms & Developers |
Disable SSL (http.sslVerify false) |
Critical Risk (Vulnerable to MITM) | Unsafe Workaround | Strictly discouraged in production |
Leave a Reply