Git ignores no_proxy/NO_PROXY and routes internal hosts through a proxy, so clone/fetch fails with "Could not resolve host" or "Connection timed out". Fix it with http.noProxy.
This problem occurs when Git keeps routing a connection through your HTTP/HTTPS proxy even though you set the `no_proxy` (or `NO_PROXY`) environment variable to bypass the proxy for that host. Git itself never prints a message that literally says "no_proxy configuration not working" — instead the failure surfaces as a generic `fatal: unable to access '<url>'` followed by a libcurl reason such as `Could not resolve host`, `Connection timed out`, `Failed to connect`, or `Received HTTP code 403/407 from proxy after CONNECT`. These all point to the same root cause: the request is being sent to the proxy instead of directly to the host you intended to reach. Git uses libcurl for HTTP/HTTPS transport. libcurl generally honors `no_proxy`, but a proxy configured in Git's own config (`http.proxy`) takes precedence over the environment variable and is not subject to `no_proxy` filtering. The result is that the proxy either cannot resolve or cannot reach an internal-only host, and the connection fails. This is common in corporate networks where an external proxy is configured globally but internal Git servers must be reached directly. The reliable fix is to express the bypass in Git's own configuration — using `http.noProxy`, or an empty per-URL `http.<url>.proxy` setting — rather than relying solely on the `no_proxy` environment variable.
First confirm the failure is proxy routing and not DNS or a server outage. Run Git with verbose curl tracing and look at where it tries to connect:
GIT_CURL_VERBOSE=1 git ls-remote https://git.internal.company.com/team/repo.gitIn the output:
- * Connected to proxy.company.com (...) port 8080 means traffic is (wrongly) going through the proxy — this is the case this article fixes.
- * Trying <internal-IP>... followed by * Connected to git.internal.company.com means Git is connecting directly and the problem lies elsewhere (DNS, firewall, certificate).
You will typically see the failure end with fatal: unable to access '...' and a libcurl reason such as Could not resolve host, Connection timed out, or Received HTTP code 407 from proxy after CONNECT. Note the exact reason — it confirms the proxy, not Git, is rejecting or failing the connection.
Identify every proxy setting that could affect Git:
# Proxy-related environment variables
env | grep -i proxy
# Git config at all levels (settings here take precedence over env vars)
git config --system --get http.proxy
git config --global --get http.proxy
git config --local --get http.proxy 2>/dev/null
git config --system --get https.proxy
git config --global --get https.proxy
git config --local --get https.proxy 2>/dev/null
# Existing bypass setting, if any
git config --global --get http.noProxyIf http.proxy is set anywhere in Git config, that value is used for matching URLs and is not filtered by the no_proxy environment variable. That is the most common reason a correct no_proxy appears to be ignored.
The most reliable fix is to declare the bypass in Git's own config with http.noProxy (a comma-separated host list), so it applies regardless of how the proxy was set:
# Hosts to bypass the proxy for
git config --global http.noProxy "internal.company.com,git.local,localhost,127.0.0.1"
# Wildcards for subdomains are supported
git config --global http.noProxy "*.internal.company.com,localhost,127.0.0.1"
# Verify
git config --global --get http.noProxyEquivalent .gitconfig:
[http]
proxy = http://proxy.company.com:8080
noProxy = internal.company.com,git.local,localhostRe-run the verbose command from step 1; you should now see Git connect directly to the internal host instead of the proxy.
For per-host control, set an empty proxy for the exact Git server. An empty value disables the proxy for matching URLs while leaving the global proxy in place for everything else:
# Disable the proxy for one host
git config --global http.https://git.internal.company.com.proxy ""
# Disable for all subdomains
git config --global http.https://*.internal.company.com.proxy ""Equivalent .gitconfig:
[http]
proxy = http://proxy.company.com:8080
[http "https://git.internal.company.com"]
proxy =
[http "https://gitlab.local"]
proxy =This is the most precise option when only one or two internal hosts need to bypass the proxy.
If you rely on the environment variable, make sure the syntax is exactly right — small formatting mistakes silently disable it:
# Correct: comma-separated, no spaces, no scheme
export no_proxy="localhost,127.0.0.1,.internal.company.com,git.local"
export NO_PROXY="$no_proxy"
# A leading dot matches subdomains:
# .company.com -> matches git.company.com, repo.company.com
# company.com -> matches only company.com itselfCommon mistakes that break it:
export no_proxy="localhost, 127.0.0.1" # spaces after commas
export no_proxy="localhost;127.0.0.1" # semicolons are not separators
export no_proxy="https://internal.company.com" # do not include a schemeWindows Command Prompt:
set no_proxy=localhost,127.0.0.1,.internal.company.comWindows PowerShell:
$env:no_proxy = "localhost,127.0.0.1,.internal.company.com"Make it permanent by adding the export lines to ~/.bashrc or ~/.zshrc. Remember: this only helps when the proxy comes from the environment, not when it is set in Git config (see step 6).
If a stray http.proxy in Git config is forcing the proxy, remove it so the environment variable or your bypass rules take effect:
# System level (may require sudo)
git config --system --unset http.proxy
git config --system --unset https.proxy
# Global level
git config --global --unset http.proxy
git config --global --unset https.proxy
# Local repository level (run inside the repo)
git config --local --unset http.proxy
git config --local --unset https.proxy
# Show what remains and where it comes from
git config --list --show-origin | grep -i proxyThe --show-origin listing tells you exactly which file each remaining proxy setting lives in, so you can target the right one.
Verify the host is now reached directly:
# curl uses the same libcurl as Git — a quick sanity check
curl -v https://git.internal.company.com 2>&1 | grep -E 'Connected to|Trying'
# Git with verbose tracing
GIT_CURL_VERBOSE=1 git ls-remote https://git.internal.company.com/team/repo.gitSuccess looks like:
- * Trying <internal-IP>... and * Connected to git.internal.company.com (direct connection)
- No Connected to proxy... line for the internal host
- The command completes without fatal: unable to access
If HTTP proxy bypass remains unreliable, switching the remote to SSH avoids the HTTP proxy path entirely:
# Clone over SSH
git clone [email protected]:team/repo.git
# Or convert an existing remote
git remote set-url origin [email protected]:team/repo.git
git remote -vSSH uses port 22 and does not traverse the HTTP proxy. If your network forces SSH through a jump host or blocks direct SSH, configure ~/.ssh/config to reach the internal host directly:
Host git.internal.company.com
User git
IdentityFile ~/.ssh/id_ed25519
# If a global ProxyJump/ProxyCommand is set elsewhere, override it:
ProxyCommand noneCI runners need the bypass set in their own environment, since they do not inherit your interactive shell config. Set both the env vars and the Git config:
GitHub Actions (self-hosted runner):
jobs:
build:
runs-on: self-hosted
env:
no_proxy: "git.internal.company.com,localhost,127.0.0.1"
NO_PROXY: "git.internal.company.com,localhost,127.0.0.1"
steps:
- name: Configure Git proxy bypass
run: git config --global http.https://git.internal.company.com.proxy ""
- uses: actions/checkout@v4GitLab CI:
variables:
no_proxy: "git.internal.company.com,localhost"
NO_PROXY: "git.internal.company.com,localhost"
before_script:
- git config --global http.https://git.internal.company.com.proxy ""Jenkins Pipeline:
environment {
no_proxy = 'git.internal.company.com,localhost'
NO_PROXY = 'git.internal.company.com,localhost'
}### How Git chooses a proxy
For a given URL, Git resolves the proxy in this order (highest priority first):
1. URL-specific http.<url>.proxy Git config
2. General http.proxy Git config
3. HTTPS_PROXY / https_proxy environment variable (for HTTPS URLs)
4. HTTP_PROXY / http_proxy environment variable (for HTTP URLs)
The no_proxy / NO_PROXY environment variable is applied by libcurl to proxies that come from the environment. A proxy set in Git config (http.proxy) is passed straight to libcurl and is not filtered by the environment no_proxy. This is the single most common reason a correct no_proxy looks like it is being ignored — and why the in-config http.noProxy (step 3) or empty per-URL proxy (step 4) is the dependable fix.
### Git for Windows specifics
Git for Windows may not honor a Unix-style no_proxy set only for the current shell. Prefer setting it persistently and using Git's own config:
# Persist the env var for the Windows user
setx no_proxy "localhost,127.0.0.1,.company.com"
# Or rely on Git config, which is platform-independent
git config --global http.noProxy "localhost,127.0.0.1,.company.com"### CIDR ranges in no_proxy
Newer libcurl supports CIDR notation in no_proxy, but the version bundled with older Git builds may not:
# Works only with recent libcurl
export no_proxy="localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16"
# Portable fallback: list explicit hostnames/IPs
export no_proxy="localhost,127.0.0.1,git.internal.company.com,10.0.1.50"Check your libcurl version with curl --version (Git uses the same library) if range matching is not taking effect.
### Proxy auto-configuration (PAC) files
If your organization distributes a PAC file, the proxy choice can be made by JavaScript logic that does not consult no_proxy at all. On macOS, inspect the active system proxy:
scutil --proxyIf a PAC URL is in force and routes your internal host through the proxy, set the bypass explicitly in Git config (steps 3-4) and/or ask your network team to add the internal hosts to the PAC exclusion logic.
### Deeper debugging
For stubborn cases, enable full tracing and capture it to a file:
GIT_TRACE=1 GIT_CURL_VERBOSE=1 git fetch origin 2>&1 | tee git-debug.logKey lines to look for:
- * Trying <IP>... — a direct connection attempt (good)
- * Connected to <proxy> — the request is going through the proxy
- * Establish HTTP proxy tunnel to <host>:443 / CONNECT <host>:443 — HTTPS tunneling through the proxy
- Received HTTP code 407 from proxy after CONNECT — the proxy is demanding authentication for traffic that should have bypassed it
ssh: Could not resolve hostname github.com: Name or service not known
How to fix 'ssh: Could not resolve hostname github.com: Name or service not known' in Git
error: insufficient permission for adding an object to repository database .git/objects
How to fix "insufficient permission for adding an object to repository database" in Git
fatal: could not create work tree dir 'repo': Permission denied
How to fix "could not create work tree dir: Permission denied" in Git
Smudge error: Error downloading object: The requested URL returned error
How to fix Git LFS 'Smudge error: Error downloading object' error
fetch-pack: unexpected disconnect while reading sideband packet
How to fix 'unexpected disconnect while reading sideband packet' in Git