Git behind a proxy fails in a small number of recognisable ways, and each failure names itself in the last line of the error. "Could not resolve proxy" is one setting left over from another network. "Received HTTP code 407 from proxy after CONNECT" is a proxy that wants a login. "Connection refused" on a proxy port is a proxy that is not there. "SSL certificate problem: unable to get local issuer certificate" is a proxy that inspects your traffic and a git that does not trust it. The messages come from curl, the library git uses for HTTP, which is why they read exactly like curl's own errors, and why the fixes are configuration rather than code.
This guide covers how git decides which proxy to use, the commands to set and remove it in each scope, and the fix for each error in turn. It ends with the case that catches everyone at least once: the proxy that follows a laptop home.
How git picks a proxy
Git reads its proxy from three places, and the first match wins.
- A per-URL setting.
http.<url>.proxyapplies only to remotes that match the URL prefix.git config --global http.https://github.com.proxy http://proxy.example.com:3128sends GitHub traffic through the proxy and nothing else. - The general setting.
http.proxyapplies to every HTTP and HTTPS remote. There is nohttps.proxykey; guides that suggest one are describing a setting git never reads.http.proxycovers both schemes. - The environment. Because git speaks HTTP through curl, the
http_proxy,https_proxy,all_proxy, andno_proxyvariables that curl honours apply to git too, in lower or upper case. A proxy exported in a shell profile is a git proxy whether or notgit configmentions it.
Scope matters within the config. A setting in the repository's own .git/config overrides --global (~/.gitconfig), which overrides --system. The one command that shows all of it, with the file each line came from, is:
git config --list --show-origin | grep -i proxy
env | grep -i proxy
Run both before changing anything. Half of all git proxy problems are a setting nobody remembers making.
Setting the proxy
For everything:
git config --global http.proxy http://proxy.example.com:3128
With credentials, URL-encoded (a password p@ss becomes p%40ss):
git config --global http.proxy http://alice:p%40ss@proxy.example.com:3128
For one host only, so that internal servers stay direct:
git config --global http.https://github.com.proxy http://proxy.example.com:3128
For a single command, without touching the config:
git -c http.proxy=http://proxy.example.com:3128 clone https://github.com/org/repo.git
Through a SOCKS proxy, using the socks5h scheme so that hostnames resolve on the proxy side rather than on your machine:
git config --global http.proxy socks5h://127.0.0.1:1080
Exempting one host from a general proxy, so the proxy carries the internet but not the company's own git server, is done with an empty per-URL value:
git config --global http.https://git.internal.example.com.proxy ""
The equivalent for the environment is no_proxy=git.internal.example.com,localhost,.corp.
Removing the proxy
git config --global --unset http.proxy
git config --global --unset-all http.proxy
git config --unset http.proxy
The first removes one global value, the second removes every global value if the key was set more than once, and the third, run inside a repository, removes a local override. Then clear the environment for the session with unset http_proxy https_proxy all_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY, and remove the export from ~/.bashrc, ~/.zshrc, or the Windows environment variables so it does not return at the next shell. Confirm with the two listing commands above.
The errors, one by one
| Last line of the error | What it means | Fix |
|---|---|---|
Could not resolve proxy: proxy.example.com | The proxy hostname does not resolve on this network | Unset it, or make it per-URL |
Failed to connect to proxy.example.com port 3128 ... Connection refused | Nothing is listening at that proxy address | Wrong port, proxy down, or off-network |
Received HTTP code 407 from proxy after CONNECT | The proxy wants credentials | Credentials in the URL, or proxyAuthMethod |
SSL certificate problem: unable to get local issuer certificate | The proxy re-signs HTTPS with a CA git does not trust | http.sslCAInfo or http.sslBackend schannel |
SSL certificate problem: self signed certificate in certificate chain | Same, with a self-signed root | Same |
RPC failed; curl 56 ... or HTTP 408 during push | The proxy cut a large upload | http.postBuffer, or SSH |
ssh: connect to host github.com port 22: Connection timed out | The proxy does not carry SSH | HTTPS remote, port 443, or ProxyCommand |
Could not resolve proxy
The classic. A proxy was configured on a network where its name exists, and now you are on one where it does not: at home with the office proxy still set, or on a VPN that no longer provides the office DNS. Git tries to look the name up before anything else and stops there. Find the setting with the two listing commands and remove it, or turn it into a per-URL setting for the hosts that genuinely need it. If you move between networks daily, the environment variable is the better home for the proxy, since a shell function or a network-aware profile can set and unset it without touching git's config.
Connection refused on the proxy port
The name resolved, and nothing answered. Either the port is wrong (3128 and 8080 are the common ones), the proxy process is down, or you are on a network from which the proxy is not reachable. Test with curl, which speaks the same library: curl -v -x http://proxy.example.com:3128 https://github.com/ -o /dev/null. If curl fails the same way, the proxy is the problem, and our guide to curl proxy errors covers the diagnosis; if curl succeeds and git fails, git's config points somewhere different from what you think, and the listing commands will show where.
407 after CONNECT
The proxy requires authentication for the tunnel git needs to reach an HTTPS remote. Git does not prompt for proxy credentials; they go in the proxy URL, URL-encoded. If the proxy uses NTLM or Kerberos instead of Basic, git's http.proxyAuthMethod setting selects the scheme (basic, digest, negotiate, ntlm), and on Windows the Negotiate method can use your logged-in identity without a password in the URL. Where none of that works, the standard workaround is a small local relay that authenticates to the corporate proxy on your behalf and exposes an unauthenticated proxy on 127.0.0.1, which git then uses. The special-character and whitelist cases are in 407 Proxy Authentication Required.
The SSL certificate problem
An inspecting proxy terminates your HTTPS connection, reads it, and re-encrypts it with a certificate signed by the organisation's own authority. Browsers on managed machines trust that authority because IT installed it in the system store; git ships its own certificate bundle and does not. The fix is to give git the authority's root certificate:
git config --global http.sslCAInfo /path/to/corporate-root.pem
On Windows, Git for Windows can use the operating system's certificate store instead of its bundle, which usually already contains the authority:
git config --global http.sslBackend schannel
What not to do, except as a one-off to confirm the diagnosis, is git config --global http.sslVerify false. It tells git to trust whatever is in the middle of every connection, forever, for every host, which is the precise thing certificate verification exists to prevent. Use it once with -c on a single command if you must; do not set it globally.
Pushes that die through the proxy
A large push through some proxies fails with a curl 56 or an HTTP 408, because the proxy buffers the upload and gives up. Raising git's buffer, git config --global http.postBuffer 524288000, helps with proxies that need the whole request before forwarding. The more durable fix is to push over SSH, which the proxy does not inspect, using one of the routes below.
SSH remotes and the proxy
http.proxy does nothing for git@github.com:org/repo.git, because that is an SSH connection, and most corporate proxies do not carry port 22. Three ways through. Switch the remote to HTTPS (git remote set-url origin https://github.com/org/repo.git), and use a credential helper for the login. Use GitHub's SSH endpoint on port 443, which passes through proxies that allow HTTPS: in ~/.ssh/config, Host github.com with HostName ssh.github.com and Port 443. Or tunnel SSH through the proxy's CONNECT method with a ProxyCommand line, for example ProxyCommand nc -X connect -x proxy.example.com:3128 %h %p with OpenBSD netcat, or corkscrew proxy.example.com 3128 %h %p where corkscrew is installed.
The proxy that follows the laptop home
The single most common git proxy complaint is not about proxies at all. It is a laptop configured for an office network that fails everywhere else, with "Could not resolve proxy" at home and a timeout at the coffee shop. The clean solution is to stop making the proxy global. Set it per-URL for the hosts that need it, or set it in a shell function that you call on the office network and leave alone elsewhere, or rely on the operating system's proxy where git can see it through the environment. A global http.proxy is the right setting only on a machine that never leaves the network the proxy lives on.
Where a proxy of your own fits
Almost nobody needs a commercial proxy for day-to-day git; the proxies in this guide are the ones an organisation puts in your way. The exception is automation: mirrors and pipelines that clone from many hosts at volume, from infrastructure whose address is rate-limited or blocked by a hosting provider, and which need a stable exit that is not shared with the rest of the cloud. For that, a fixed-address ISP proxy in the per-URL setting above does the job, and our curl guide shows how to verify any proxy from the shell before git relies on it.
Before you file a ticket with IT
List first: git config --list --show-origin | grep -i proxy and env | grep -i proxy. Set with http.proxy or per-URL http.<url>.proxy, never https.proxy. Credentials go in the URL, encoded. Trust the corporate authority with http.sslCAInfo, not by disabling verification. SSH remotes need their own route. And when the error says "could not resolve proxy", the fix is to remove a setting, not to add one.