Guide

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

curl: (5) Could not resolve proxy: GET means -x was typed for -X. The other exit-5 causes, and every exit-97 SOCKS message, tested in curl 8.21 and 8.16.

HProxy Team··Updated September 27, 2026·11 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→

curl: (5) Could not resolve proxy means curl was told to use a proxy and could not use the address it got. It stops before it contacts anything. curl: (97) means the opposite end: curl reached a SOCKS proxy, and the handshake with it failed. Neither has anything to do with the site you wanted.

We reproduced both on 27 September 2026, with the curl that ships with Windows (8.21.0) and the curl of Git for Windows (8.16.0). The lab had a site that only a proxy can reach and a set of lab proxies, each set up to fail one way. Both builds gave the same exit code in all but two cases, both of them a SOCKS proxy with the site's name looked up on your own machine, shown below. Our guide to exit codes 7, 56 and 60 covers the other proxy failures.

First check: -x is the proxy, -X is the method

Read the name after the colon. If it says GET, POST, PUT or DELETE, the cause is one letter:

$ curl -x GET https://example.com/
curl: (5) Could not resolve proxy: GET

Lower-case -x sets a proxy, so curl tried to find a proxy named GET. Capital -X sets the request method. Both curl builds printed exactly that line, and -x POST printed Could not resolve proxy: POST. With -X GET the same request went through.

curl -X POST -d 'a=1' https://example.com/api

This slip is behind several Stack Overflow questions: Could not resolve proxy: POST in a Watson script, DELETE against a Hadoop server, -xPOST in an Elasticsearch import. The top answers, and one asker's own edit, all come to the same fix: use -X. Its long form, --request, does the same.

Where curl gets a proxy from

If the name after the colon is a real host name, the proxy came from one of three places, and it is often one you forgot:

  1. The command line: -x or --proxy, or the SOCKS options --socks5, --socks5-hostname, --socks4 and --socks4a. An address with no scheme counts as an HTTP proxy.
  2. The environment: HTTPS_PROXY for https:// sites, ALL_PROXY for everything, and http_proxy for plain http:// sites. NO_PROXY lists hosts to reach without a proxy.
  3. A config file: a proxy = ... line in .curlrc applies to every command. curl looks in CURL_HOME first, then in the home folder. On Windows it takes _curlrc as well as .curlrc.

Each of these gave exit 5 in our lab when it named a proxy that does not exist: the flag, HTTPS_PROXY, https_proxy, ALL_PROXY, and a .curlrc or _curlrc in CURL_HOME. -q as the first argument made curl skip the config file.

One rule differs by system. curl documents http_proxy as lower case only, and adds that some systems, like Windows, do not tell the cases apart. We saw both sides:

  • On Linux (our server, curl 8.5.0), HTTP_PROXY in capitals was ignored, and http_proxy was used.
  • On Windows, both builds used HTTP_PROXY in capitals for an http:// site, because on Windows the two names are one variable.

HTTP_PROXY never applies to https:// sites. With only HTTP_PROXY set, an https:// request went straight out and failed on the site's name.

To find a forgotten proxy:

  • bash, macOS and Git Bash: env | grep -i proxy, then cat ~/.curlrc.
  • PowerShell: Get-ChildItem Env: | Where-Object Name -like '*proxy*'.
  • cmd: set HTTP lists every variable that starts with HTTP, which shows HTTP_PROXY and HTTPS_PROXY at once, and set ALL shows ALL_PROXY.

Then fix the value or remove it, and remove the line that sets it, in a shell profile or in the Windows environment variables, so it does not come back. For one command, --noproxy "*" switches the proxy off: in our test it bypassed a broken proxy variable. NO_PROXY does the same for the hosts it names. A proxy name you do not recognise on a personal machine deserves the same care as an unknown proxy in the system settings: find what set it before you remove it. The Windows and macOS side is in proxy settings that keep turning back on.

curl (5): what the name after the colon tells you

Exit 5 covers two different problems. Either curl could not look the proxy up (Could not resolve proxy), or it could not read the address at all (Unsupported proxy syntax). Both builds printed these:

You gave curlcurl printed
-x GET(5) Could not resolve proxy: GET
a proxy name that does not exist here(5) Could not resolve proxy: proxy.invalid
a space at the end of the address(5) Unsupported proxy syntax ...: Malformed input to a URL function
quotes inside the value(5) Unsupported proxy syntax ...: Port number was not a decimal number between 0 and 65535
a ; where the : goes(5) Unsupported proxy syntax ...: Bad hostname
a raw @ in the password(5) Unsupported proxy syntax ...: Bad hostname
htp:// instead of http://(7) Unsupported proxy scheme for 'htp://...'

The quotes case has a common source on Windows. In cmd, set HTTPS_PROXY="http://proxy.example.com:3128" keeps the quotes as part of the value, as Microsoft's documentation for set says, and curl then stopped with exit 5. set "HTTPS_PROXY=http://proxy.example.com:3128", with the quotes around the whole assignment, worked. A misspelt scheme is the one address mistake that is not exit 5 but 7. The @ case, and how to write symbols in a proxy password, is in our 407 guide.

A real host name after the colon, such as proxy.corp.example.com, can be a company proxy on a laptop that is now on another network. That is the story of a much-read Stack Overflow question about git, whose proxy from work came back at home. Remove the setting, or turn it off with --noproxy "*" until you are back.

Our own console window: the curl 5 and 97 lab of 27 September 2026. -x GET, a proxy name that does not exist, HTTPS_PROXY, HTTP_PROXY in capitals and a .curlrc all gave (5) Could not resolve proxy. A trailing space and cmd's quoted set gave (5) Unsupported proxy syntax. htp:// gave (7), an https:// proxy address (35), and --socks5 with a name only the proxy knows (6) in curl 8.21.0 and (97) in 8.16.0. The SOCKS5 failures all gave (97): no acceptable method, user rejected, reply 5, invalid version. http:// pointed at a SOCKS proxy gave (56).
Captured on our own machine on 27 September 2026: a summary of our second run. Every case gave the same result in both runs.

curl (97): the SOCKS handshake failed

Exit 97 means curl reached the proxy and the SOCKS conversation failed. curl added this code in version 7.73.0. The message says where it failed:

What happenedcurl printed
The proxy wants a login and got none(97) No authentication method was acceptable.
The login was wrong(97) User was rejected by the SOCKS5 server (1 1).
The proxy accepts no method curl offers(97) No authentication method was acceptable.
The proxy refused the site(97) cannot complete SOCKS5 connection to site.lab.test. (n)
A SOCKS4 proxy refused it(97) [SOCKS] cannot complete SOCKS4 connection to 0.0.0.0:0. (91), request rejected or failed.
socks5h:// pointed at an HTTP proxy(97) Received invalid version in initial SOCKS5 response.
socks4a:// pointed at an HTTP proxy(97) SOCKS4 reply has wrong version, version should be 0.

In User was rejected by the SOCKS5 server (1 1), the second number is the status the proxy sent back, and anything but 0 means the login failed. Check the user name and password. A password with symbols goes in -U, or percent-encoded in the address.

The number at the end of cannot complete SOCKS5 connection is the proxy's reply code from the SOCKS5 standard. We had the proxy answer with each code in turn:

CodeThe standard calls it
1general SOCKS server failure
2connection not allowed by ruleset
3network unreachable
4host unreachable
5connection refused
6TTL expired
7command not supported
8address type not supported

Code 1 is the proxy's own failure. Code 2 is its rules saying no to that site or port. Codes 3 to 5 are the proxy failing to reach the site. In every case the site never saw you.

The wrong protocol shows itself too. A socks5h:// address pointed at an HTTP proxy got Received invalid version in initial SOCKS5 response., because the HTTP proxy answered with an error page instead of a SOCKS reply. The other way round, http:// pointed at a SOCKS proxy, gave (56) Proxy CONNECT aborted. The SOCKS standard puts SOCKS on port 1080 by convention, but a port says nothing for sure; our proxy checker tests an address on HTTP, HTTPS, SOCKS4 and SOCKS5.

Two cases changed between the two builds: --socks5 and socks4://. Both look the site's name up on your own machine, while --socks5-hostname, or socks5h://, lets the proxy do it. For a name that only the proxy can resolve, curl 8.21.0 said (6) Could not resolve host: site.lab.test in both cases. curl 8.16.0 said (97) Could not resolve proxy: 127.0.0.1: it names the proxy, although the name that failed was the site's. With socks4:// it never even reached the proxy. With --socks5-hostname, both builds worked. More on each SOCKS failure is in our guide to SOCKS5 proxy errors.

Two neighbours worth knowing

curl (35) with a proxy has one common cause: a proxy address that starts with https://. That tells curl to speak TLS to the proxy itself, and a proxy that listens in plain HTTP cannot answer. In our test, both Windows builds gave (35) schannel: next InitializeSecurityContext failed: SEC_E_INVALID_TOKEN (0x80090308), with the rest of the line in the language of Windows. Use http:// in the proxy address. It still carries https:// sites, through a tunnel.

curl in Windows PowerShell 5.1 is not curl. There, curl is an alias for Invoke-WebRequest, a different program with different options. Type curl.exe to get the real one, or use PowerShell 7, where the alias is gone.

The full set of curl proxy exit codes

Exit codecurl's messageWhere it fails
5Could not resolve proxy, or Unsupported proxy syntaxBefore contacting anything
6Could not resolve hostThe site's name, looked up on your machine
7Unsupported proxy scheme, Failed to connect, and from 8.20.0 CONNECT tunnel failedThe scheme, the connection, or the tunnel
35SSL connect errorTLS to a proxy that speaks plain HTTP
56CONNECT tunnel failed (up to 8.19.0), Proxy CONNECT abortedThe tunnel, or a closed connection
60SSL certificate problemVerifying the site, or an inspecting proxy
97Proxy handshake errorThe SOCKS conversation with the proxy

Codes 7, 56 and 60 have their own guide, curl 7, 56 and 60, and 97 is also in the SOCKS5 guide. The tunnel failure moved from exit 56 to exit 7 in curl 8.20.0, with the same message, CONNECT tunnel failed, response 407 for example. Our 407 guide shows both.

Testing a proxy properly from the shell

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

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

For SOCKS, letting the proxy resolve the name:

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

On Windows, write -o NUL. The last line tells you which layer failed: exit 5 is the address, 7 the connection or the tunnel, 97 the SOCKS handshake. Using proxies with curl covers the options in full. To rule out the network, try an address from our free proxy list, free to use with no signup and no key.

Exit 5 and exit 97 side by side

Exit 5: read the name after the colon. GET or POST means -x was meant as -X. A host name means a proxy from the flag, a variable or .curlrc: find it and remove it, or skip it with --noproxy "*". Unsupported proxy syntax means an address curl cannot read: look for a space, quotes or a stray symbol.

Exit 97: in curl 8.21.0, curl reached the proxy. Read the message: a missing or wrong login, a numbered refusal from the proxy, or a proxy that is not SOCKS at all. Older builds such as 8.16.0 also gave 97 when the site's name failed on your own machine, before the proxy ever got the name.

Our own lines come as host:port:username:password, with the login inside. Each client takes those four parts in its own syntax. Pasted into curl as they are, they stop with exit 5 and Unsupported proxy syntax. For curl, write -x http://username:password@host:port.

How we tested

On 27 September 2026 we ran one lab on a Windows 11 machine, twice.

  • The site. site.lab.test ran on the machine itself, over HTTP and over HTTPS with a certificate from a lab authority. The name exists nowhere else, so only a proxy could reach it.
  • The proxy that does not exist. proxy.invalid never resolves anywhere, which makes it a safe stand-in for a proxy that only exists on another network.
  • The lab proxies, all on the same machine:
    • an open HTTP proxy;
    • a SOCKS proxy for versions 4, 4a and 5;
    • a SOCKS5 proxy that wanted a login;
    • eight SOCKS5 proxies that answered with reply codes 1 to 8;
    • one that accepted no method.
  • The clients. curl 8.21.0 (the curl in Windows) and 8.16.0 (Git for Windows), 44 cases each. Every case ran without proxy variables and, except the config-file cases, with -q; the machine has no curl config file.
  • Linux. The HTTP_PROXY check ran on our own server with curl 8.5.0.

All 88 cases gave the same result in both runs.

Sources

Frequently asked questions

What does curl: (5) Could not resolve proxy: GET mean?
You typed -x GET instead of -X GET. Lower-case -x sets a proxy, so curl tried to use a proxy named GET and could not find it. Capital -X sets the request method. The same happens with POST, PUT and DELETE, and with the attached form -xPOST. Use -X, or write it out as --request.
What does curl (5) Could not resolve proxy mean?
curl was told to use a proxy and could not look its name up, so it stopped before contacting anything. The name after the colon is the one it tried. It came from -x, from a proxy variable such as HTTPS_PROXY, or from a proxy line in .curlrc. Exit 5 also covers a proxy address curl cannot read at all, shown as Unsupported proxy syntax.
Why does curl use a proxy I did not pass on the command line?
Because curl reads proxies from the environment (HTTPS_PROXY, ALL_PROXY, and http_proxy for plain http:// sites) and from a proxy line in .curlrc. On Linux, http_proxy counts only in lower case. On Windows, variable names ignore case, so HTTP_PROXY counts too; in our test it did. Put -q first on the command line to skip .curlrc.
How do I make curl ignore the proxy for one command?
Add --noproxy "*". It matches every host and turns the proxy off for that command; in our test it bypassed a broken proxy variable. To exclude some hosts for good, list them in NO_PROXY. To stop a variable for the whole session, remove it: unset in bash, Remove-Item Env:HTTPS_PROXY in PowerShell, set HTTPS_PROXY= in cmd.
What does curl (97) mean?
curl reached the proxy and the SOCKS handshake failed. The message says where. No authentication method was acceptable means the proxy wants a login you did not send. User was rejected means a wrong login. cannot complete SOCKS5 connection with a number is the proxy refusing the site, and the number is its reply code: 1 general failure, 2 not allowed, 3 network unreachable, 4 host unreachable, 5 refused. Received invalid version means the proxy is not SOCKS at all. In older builds such as 8.16.0, Could not resolve proxy with exit 97 can also mean the site's name failed on your own machine: use --socks5-hostname.
Why does curl say (35) when I use a proxy?
The proxy address starts with https://, which tells curl to speak TLS to the proxy itself. A proxy that listens in plain HTTP cannot answer that. In our test on Windows it gave exit 35, schannel: next InitializeSecurityContext failed: SEC_E_INVALID_TOKEN. Use http:// for the proxy address, even when the site is https://.
Why does curl behave differently in PowerShell?
In Windows PowerShell 5.1, curl is an alias for Invoke-WebRequest, a different program with different options. Run curl.exe to get the real curl that ships with Windows, or use PowerShell 7, where the alias is gone. Every command on this page assumes the real curl.

Get proxies that are alive right now

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. 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

HProxy.

Honest guides and comparisons on proxies, scraping and staying unblocked, from the team that runs the network.

RSS feed