Guide

curl: (5) Could Not Resolve Proxy, and curl (97) Proxy Handshake Error: Causes and Fixes

curl exit 5 means the proxy's hostname did not resolve, usually a leftover variable or a typo. Exit 97 is a failed proxy handshake, usually SOCKS. The fixes for both.

HProxy Team··6 min read
HProxy.Guide

Skip the dead lists.

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump.

Open the free proxy list

Most curl proxy failures are exit code 7 (could not connect), 56 (the connection died), or 60 (a certificate problem), and our guide to those three covers them. Two others turn up often enough to deserve their own page, and they are different in kind. Exit 5, "Could not resolve proxy", happens before curl has contacted anything: it was told to use a proxy and could not look the proxy's name up. Exit 97, "Proxy handshake error", happens after curl has reached the proxy: the two of them could not agree on how to proceed, which in practice means a SOCKS negotiation failed. One is a configuration leftover, the other a protocol conversation, and neither has much to do with the site you were trying to reach.

Where curl gets a proxy from

curl consults four sources, and the surprise in most exit-5 cases is that the proxy came from one the user forgot.

  1. The command line. -x or --proxy with a URL, and the --socks5, --socks5-hostname, --socks4, and --socks4a options for SOCKS.
  2. ~/.curlrc. A line reading proxy = http://proxy.example.com:3128 applies to every command. Windows uses _curlrc in the user's profile directory.
  3. The environment. http_proxy for plain HTTP requests, HTTPS_PROXY or https_proxy for HTTPS ones, ALL_PROXY or all_proxy as a fallback for everything, and NO_PROXY or no_proxy for exclusions. One quirk is worth memorising: curl reads http_proxy in lower case only, for a security reason dating back to CGI environments, while the HTTPS and ALL variants work in either case. A shell that exports HTTP_PROXY in upper case therefore affects HTTPS requests only through HTTPS_PROXY, and plain-HTTP requests not at all.
  4. --noproxy on the command line overrides all of the above for the hosts it names, and --noproxy '*' disables proxying for the command entirely.

curl -v settles which is in play. When a proxy is being used, the verbose output says so near the top, naming the address, before any request is sent.

curl (5): Could not resolve proxy

The name after the colon is what curl tried to resolve, and reading it usually explains the error on its own.

What the name looks likeWhat went wrongFix
proxy.corp.example.comAn office proxy configured on a machine that is now elsewhereUnset the variable or the .curlrc line off-network
htp://proxy.example.com:3128 or proxy.example.com;3128A typo in the scheme or separator, so the whole string became the hostnameFix the URL
proxy.example.com:3128 with a trailing space, or quotes inside the valueShell quoting put characters into the nameRe-export the variable cleanly
http://user:pa@ss@proxy.example.com:3128An unencoded @ in the password split the URL at the wrong placeURL-encode it: pa%40ss
A name you have never seenA leftover from a tool, a VPN, or unwanted softwareFind the source; see below

Run env | grep -i proxy and cat ~/.curlrc and the source is almost always in one of the two. Then either fix the value, or remove it:

unset http_proxy https_proxy HTTPS_PROXY all_proxy ALL_PROXY

and delete the export from ~/.bashrc, ~/.zshrc, ~/.profile, or the Windows environment variables so it does not return with the next shell. For one command without touching anything, --noproxy '*' bypasses every proxy. For a machine that moves between networks, a shell function that sets the proxy on the office network and unsets it elsewhere beats a permanent export, and NO_PROXY keeps internal hosts direct while the proxy carries the rest.

A proxy name you do not recognise, on a personal machine, deserves the same treatment as an unknown proxy in the system settings: find what set it before removing it. The Windows and macOS side is in proxy settings that keep turning back on, where the same leftovers appear in the system panels.

curl (97): Proxy handshake error

Exit 97 was introduced in curl 7.73.0 so that failures in the conversation with the proxy stop being reported as generic connection errors. It means curl connected to the proxy and the proxy-level negotiation failed. Nearly always that is SOCKS, because SOCKS has a real handshake with distinct failure points, and each of them names its cause.

Run the command with -v and read the lines after the connection is established. The three families:

  • Authentication. SOCKS5 authentication failed, or a rejection at method negotiation. The proxy wants a username and password and got none (add -U user:pass or put them in the URL), got the wrong ones, or your address is not on an IP-authenticated proxy's allowlist.
  • A SOCKS reply. The proxy accepted you and refused the request with a numbered reply: general SOCKS server failure, connection not allowed by ruleset, host unreachable, connection refused, and the rest. Each has a specific meaning and a specific fix, laid out in our guide to SOCKS5 proxy errors.
  • The wrong protocol. curl was told the proxy is SOCKS and it is HTTP, or the reverse; the handshake bytes make no sense to the other side, and curl gives up. Port 1080 is conventionally SOCKS, 8080 and 3128 conventionally HTTP, and our proxy checker tests each protocol separately for any address.

For name resolution through SOCKS, prefer --socks5-hostname (the socks5h:// form in URLs) so that the proxy resolves the target; --socks5 resolves locally, which fails for targets that only resolve on the proxy's network and reports as a host-unreachable reply.

Two neighbours worth knowing

curl (35) SSL connect error with a proxy usually means the proxy URL begins with https://. That tells curl to speak TLS to the proxy itself, and nearly every proxy listens in plain HTTP regardless of what it carries. Change the scheme to http://. The https:// form exists for the rare proxy that terminates TLS on its listening port, and for those --proxy-cacert and --proxy-insecure are the proxy-side equivalents of --cacert and -k.

curl in Windows PowerShell 5 is not curl. curl there is an alias for Invoke-WebRequest, which has different options and prints different errors, and -x means nothing to it. Run curl.exe explicitly to get the real curl that ships with Windows 10 and 11, or use PowerShell 7, where the alias was removed.

The full set of curl proxy exit codes

Exit codecurl's messageWhere it failsGuide
5Could not resolve proxyBefore contacting anythingThis page
7Failed to connect to proxyOpening the connection to the proxycurl 7, 56, 60
35SSL connect errorTLS to a proxy that speaks plain HTTPThis page
56Received HTTP code N from proxy after CONNECT, or Recv failureThe proxy's answer to the tunnel, or a dropped connectioncurl 7, 56, 60
60SSL certificate problemVerifying the target, or an inspecting proxycurl 7, 56, 60
97Proxy handshake errorThe SOCKS negotiation with the proxyThis page and the SOCKS5 guide

Testing a proxy properly from the shell

The command that answers most questions about a proxy in one go:

curl -v -x http://user:pass@proxy.example.com:3128 https://example.com/ -o /dev/null

For SOCKS:

curl -v --socks5-hostname proxy.example.com:1080 -U user:pass https://example.com/ -o /dev/null

The verbose output shows whether the proxy resolved (exit 5 territory), whether it answered (exit 7), what it said to the tunnel (exit 56), and how the SOCKS handshake went (exit 97). Using proxies with curl covers the options in full, and every address on our free proxy list carries the result of the last handshake on each protocol, which is the quickest way to avoid testing a SOCKS proxy that is actually an HTTP one.

Exit 5 and exit 97 side by side

Exit 5: read the name after the colon, find it in env | grep -i proxy or ~/.curlrc, and fix or remove it; --noproxy '*' bypasses it for one command. Exit 97: the proxy answered and the handshake failed, so read -v for the SOCKS detail, check credentials and the allowlist, and confirm the port is actually SOCKS. And remember that http_proxy is lower case only.

Frequently asked questions

What does curl (5) Could not resolve proxy mean?
curl was told to use a proxy and could not turn the proxy's hostname into an address, so it stopped before contacting anything. The name after the colon is the one it tried. It came from the -x flag, a proxy line in .curlrc, or one of the proxy environment variables, and it either has a typo, includes characters that are not part of a hostname, or names a proxy that only exists on another network. env | grep -i proxy and cat ~/.curlrc find it.
Why does curl use a proxy I did not pass on the command line?
Because curl reads proxies from the environment: http_proxy (lower case only), HTTPS_PROXY or https_proxy, ALL_PROXY or all_proxy, and it reads a proxy line from ~/.curlrc. A variable exported in a shell profile, or set by a corporate login script, is a curl proxy on every command. curl -v prints Trying proxy or the proxy address at the top of its output, which confirms one is in play.
How do I make curl ignore the proxy for one command?
Add --noproxy '*' to bypass every proxy for that command, or --noproxy example.com to bypass it for one host. For a session, unset http_proxy https_proxy HTTPS_PROXY all_proxy ALL_PROXY. To exclude hosts permanently, set NO_PROXY or no_proxy to a comma-separated list; a leading dot matches subdomains.
What does curl (97) Proxy handshake error mean?
curl reached the proxy and the proxy-level negotiation failed, which since curl 7.73.0 is reported as exit 97 rather than folded into a generic connection error. In practice it is a SOCKS proxy that rejected the handshake: wrong or missing credentials, an authentication method the proxy does not accept, or a SOCKS reply such as general SOCKS server failure or connection not allowed by ruleset. curl -v shows the detail, and the SOCKS reply codes each name their cause.
Why does curl say (35) SSL connect error when I use a proxy?
The proxy URL given to -x starts with https://, which tells curl to speak TLS to the proxy itself. Nearly all proxies listen in plain HTTP even though they carry HTTPS traffic, so the TLS handshake fails. Use http:// in the proxy URL. https:// proxy URLs are only for proxies that genuinely terminate TLS on their listening port, which is rare.
Why does curl behave differently in PowerShell?
In Windows PowerShell 5, curl is an alias for Invoke-WebRequest, a different program with different options and different errors, and it does not understand -x. Run curl.exe explicitly to get the real curl that ships with Windows 10 and 11, or use PowerShell 7 where the alias is gone. Every command in this guide assumes the real curl.

Get proxies that are alive right now

Our free list re-checks every exit every few minutes and shows a last-checked time, so you copy IPs that worked moments ago, not a stale text dump. When the location has to survive a real check, the paid network holds up.

129M+ proxy checks run · 100+ countries · HTTP / HTTPS / SOCKS · re-checked every few minutes · no signup