Fixing curl: (56) CONNECT tunnel failed, response 407
The number at the end is the proxy talking. Here is what each one means, every other curl exit code a proxy produced, and why git fails where curl works.
In short
407 after response means the proxy rejected your login: check -U "USER:PASS". 403 on our gateway is a username value it can’t read, 465 a filter no exit matches. If git fails through a proxy that works in curl, set git config --global http.proxyAuthMethod basic.
For an https:// URL, curl first asks the proxy to open a tunnel: CONNECT ipinfo.io:443, with your proxy login. Only if the proxy answers 200 does curl start TLS with the website. Any other answer ends the request, and curl prints the proxy’s status:
curl: (56) CONNECT tunnel failed, response 407 (curl 8.14)
curl: (56) Received HTTP code 407 from proxy after CONNECT (curl 7.64)Both lines mean the same thing; the wording changed between curl versions. The website was never contacted. To print just the proxy’s status in a script, ask for it:
curl -s -o /dev/null -w '%{http_connect}\n' -x http://via.proxies.vision:9000 -U "USER-country-de:PASS" https://ipinfo.io/jsonFor an http:// URL there is no tunnel. The proxy’s refusal comes back as the response, curl exits 0, and a script that only checks the exit code thinks it worked. Add --fail or check %{http_code}.
Every exit code we hit
One mistake at a time against our gateway, https:// target unless noted.
| What we broke | curl printed | Fix |
|---|---|---|
| Wrong password, or no login | (56) CONNECT tunnel failed, response 407 | Copy the login again |
| A username value the proxy can’t read (-country-usa) | (56) CONNECT tunnel failed, response 403 | Two-letter country, city written together |
| A session label on the rotating port | (56) CONNECT tunnel failed, response 403 | Sticky port 10000 for sessions |
| Filters no exit matches (Chicago in Germany) | (56) CONNECT tunnel failed, response 465 | Drop the narrowest filter |
| Wrong password, http:// target | exit 0, response 407 | Use --fail, check the status |
| https:// as the proxy scheme | (35) TLS connect error … wrong version number | Write http:// |
| An unescaped @ in the password, in the URL | (5) Unsupported proxy syntax … Bad hostname | Pass the login with -U |
| A port where nothing listens | (7) Failed to connect … Could not connect to server | Check the port |
| http:// to the SOCKS5 port | (56) Proxy CONNECT aborted | HTTP port 9000, or socks5h:// |
| socks5h:// to the HTTP port | (28) Connection timed out | SOCKS5 port 11000 |
| socks5h://, wrong password | (97) User was rejected by the SOCKS5 server | Copy the login again |
| socks5h://, filters no exit matches | (97) cannot complete SOCKS5 connection | Drop the narrowest filter |
407: the login
The proxy didn’t get a login it accepts: a typo, a reset password, or none at all. Pass it with -U "USER:PASS" (also --proxy-user) rather than in the URL; curl doesn’t parse -U as a URL, so special characters can’t break it.
403: a value in the username
Targeting goes into the username, and our gateway refuses values it can’t read. For an http:// URL its answer names the part, for example Invalid "country". A key it doesn’t know at all is ignored instead: -cc-DE gives you a working connection in a random country. Write -country-de.
465: no exit
465 isn’t a standard status. Our gateway uses it when the login is fine but no residential exit matches every filter right now. Remove the narrowest one, usually the city; a 465 that wasn’t there a minute ago is an exit that went offline.
SOCKS5: exit code 97
Over socks5h:// there are no HTTP status codes. curl reports both a wrong login and a missing exit as exit code 97, with different text. On our gateway SOCKS5 has its own port: 11000, or 12000 for sticky sessions.
git uses libcurl, but not the way the curl command does. By default it sends the CONNECT without credentials and waits for the proxy to ask which method it wants. Through our gateway that never got further, whatever the login:
The curl command sends Basic credentials with the first request, which is why it worked all along. Tell git to do the same; the environment variable GIT_HTTP_PROXY_AUTHMETHOD=basic works too, and a shallow clone of a GitHub repository went through in our test.
Commands that work
Each ran as shown, with a real login in place of USER and PASS.
# A new German exit per request
curl -x http://via.proxies.vision:9000 -U "USER-country-de:PASS" https://ipinfo.io/json
# The same exit for 10 minutes: a session label on the sticky port
curl -x http://via.proxies.vision:10000 -U "USER-country-de-session-job1-lifetime-10:PASS" https://ipinfo.io/json
# SOCKS5, the proxy resolves the hostname
curl -x socks5h://via.proxies.vision:11000 -U "USER-country-de:PASS" https://ipinfo.io/jsongit config --global http.proxy http://USER-country-de:PASS@via.proxies.vision:9000
git config --global http.proxyAuthMethod basicEnvironment variables
curl also reads https_proxy (lower case is the safe spelling for curl). In our test a plain curl https://ipinfo.io/json went through the proxy in https_proxy, login included. The same errors as above apply. Other clients: Python requests, Node fetch.
What does 'curl: (56) CONNECT tunnel failed, response 407' mean?
How do I see the proxy's status code with curl?
Why does git say 'Proxy CONNECT aborted' when curl works?
What does curl exit code 97 mean with a SOCKS5 proxy?
How do I put a password with @ into curl's proxy URL?
Keep reading
aiohttp Proxy Errors: ClientHttpProxyError 407, SOCKS5 and trust_env
aiohttp's ClientHttpProxyError explained, why its message leaks your proxy password, socks5:// without aiohttp-socks, and rotation.
6 min read · #python#errors
Playwright Proxy Errors: ERR_TUNNEL_CONNECTION_FAILED, NS_ERROR_PROXY_*
Every Playwright proxy error in Chromium and Firefox, what the proxy answered, the silent 30-second timeout on a wrong password, and SOCKS5 auth.
7 min read · #playwright#errors
Missing dependencies for SOCKS support: the Fix, and Why You See It Without SOCKS
Install requests[socks], or find the environment variable that asked for SOCKS. Plus socks5 vs socks5h and the errors that come next.
6 min read · #python#socks5
Residential proxies, pay per GB
HTTP and SOCKS5. Country, city and sticky sessions in the username. No subscription.