Why curl is the best proxy testing tool
When a proxy misbehaves in your scraper or browser, the fastest way to isolate the problem is curl. It's installed on nearly every system, supports every proxy type, and its verbose mode shows exactly what happens between you, the proxy and the target. If it works in curl, the proxy is fine and the problem is in your code.
The basics
curl -x http://gate.example.com:7777 https://api.ipify.org-x (or --proxy) sets the proxy. Add credentials inline:
curl -x http://USER:PASS@gate.example.com:7777 https://api.ipify.orgOr separately (handy when the password has special characters):
curl -x http://gate.example.com:7777 --proxy-user 'USER:P@ss:word' https://api.ipify.org-U is short for --proxy-user.

SOCKS proxies
curl -x socks5://USER:PASS@socks.example.com:1080 https://api.ipify.org # local DNS
curl -x socks5h://USER:PASS@socks.example.com:1080 https://api.ipify.org # DNS via proxy
curl -x socks4a://socks.example.com:1080 https://api.ipify.orgPrefer socks5h to avoid DNS leaks. See SOCKS5 proxies.
HTTPS proxies (TLS to the proxy)
curl -x https://USER:PASS@secure-proxy.example.com:443 https://api.ipify.orgThe https:// scheme on the proxy encrypts the connection to the proxy itself. Add --proxy-insecure only if the proxy uses a self-signed certificate you trust. See HTTP vs HTTPS proxies.
Environment variables
export https_proxy="http://USER:PASS@gate.example.com:7777"
export http_proxy="$https_proxy"
export no_proxy="localhost,127.0.0.1,.internal.example.com"
curl https://api.ipify.orgcurl reads lowercase http_proxy (uppercase HTTP_PROXY is ignored for security reasons), and either case for HTTPS_PROXY, ALL_PROXY and NO_PROXY. Use --noproxy '*' to bypass all proxies for one command.
.curlrc
Set a default proxy in ~/.curlrc:
proxy = "http://gate.example.com:7777"
proxy-user = "USER:PASS"Debugging with verbose output
curl -v -x http://USER:PASS@gate.example.com:7777 https://httpbin.org/ipWhat to look for:
Connected to gate.example.comconfirms the proxy is reachable.CONNECT httpbin.org:443is the tunnel request.HTTP/1.1 200 Connection establishedmeans the proxy accepted it.HTTP/1.1 407means authentication failed.- The TLS handshake and final response follow.
See how proxies work and common proxy errors.
Proxy tip: Want to skip proxy management on some targets? Geonode offers both raw proxies and a Scraper API that returns HTML or Markdown with optional JavaScript rendering. We compare the two approaches in testing Geonode with cURL.
Useful checks
Which IP and location?
curl -s -x http://USER:PASS@gate.example.com:7777 https://ipinfo.io/jsonWhich headers reach the target? (plain HTTP shows proxy-added headers)
curl -s -x http://USER:PASS@gate.example.com:7777 http://httpbin.org/headersTiming breakdown:
curl -s -o /dev/null -x http://USER:PASS@gate.example.com:7777 \
-w 'connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' \
https://example.comSee proxy speed test and how to check if a proxy works.
Testing a proxy list
while IFS=: read -r host port user pass; do
ip=$(curl -s --max-time 15 -x "http://$user:$pass@$host:$port" https://api.ipify.org)
echo "$host:$port -> ${ip:-FAILED}"
done < proxies.txtcurl proxy options reference
| Option | Purpose |
|---|---|
-x, --proxy | Proxy URL (scheme, host, port, optional credentials) |
-U, --proxy-user | Proxy credentials as user:pass |
--proxy-basic, --proxy-digest, --proxy-ntlm | Proxy authentication method |
--proxy-insecure | Skip TLS verification for an HTTPS proxy |
--proxy-cacert | CA bundle for an HTTPS proxy |
--noproxy | Hosts to bypass ('*' for all) |
--socks5-hostname | Legacy way to use SOCKS5 with remote DNS |
-p, --proxytunnel | Force CONNECT tunnelling even for plain HTTP |
--preproxy | A SOCKS proxy to reach the HTTP proxy through (simple chaining) |
Testing many targets through one proxy
for url in https://www.example.com https://httpbin.org/ip https://api.ipify.org; do
code=$(curl -s -o /dev/null -w '%{http_code} %{time_total}' -x http://USER:PASS@gate.example.com:7777 "$url")
echo "$url -> $code"
doneChecking rotation
for i in $(seq 1 10); do
curl -s -x http://USER:PASS@gate.example.com:7777 https://api.ipify.org; echo
done | sort | uniq -cMostly unique IPs means rotation is working. Repeats suggest sticky sessions, connection reuse or a thin pool. See what is proxy rotation.
Simple chaining with --preproxy
curl can reach an HTTP proxy via a SOCKS proxy:
curl --preproxy socks5h://socks.example.com:1080 -x http://USER:PASS@gate.example.com:7777 https://api.ipify.orgFor longer chains, use proxychains. See proxy chains.
Saving responses for debugging
curl -s -D headers.txt -o body.html -x http://USER:PASS@gate.example.com:7777 https://www.target.example/pageInspect headers.txt for status and cookies, and body.html for block pages. When a scraper fails, reproducing the request in curl with the same proxy and headers quickly shows whether the proxy or your code is at fault. See common proxy errors.
Budget tip: If your targets are lenient, a Webshare datacenter list is often the cheapest way to scale, with rotating residential traffic kept for the sites that block datacenter IPs. Our guide to testing Webshare with cURL shows the setup.
curl recipes for everyday proxy tasks
Check exit IP and organisation in one line:
curl -s -x http://USER:PASS@gate.example.com:7777 https://ipinfo.io/json | grep -E '"(ip|country|city|org)"'Send realistic browser headers through a proxy:
curl -s -x http://USER:PASS@gate.example.com:7777 \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0 Safari/537.36' \
-H 'Accept-Language: en-US,en;q=0.9' \
--compressed https://www.example.com/Follow redirects and show the chain:
curl -sIL -x http://USER:PASS@gate.example.com:7777 https://example.com | grep -iE '^(HTTP|location)'Keep cookies across requests through the same sticky session:
P="http://USER-session-abc123:PASS@gate.example.com:7777"
curl -s -c jar.txt -b jar.txt -x "$P" https://www.example.com/ -o /dev/null
curl -s -c jar.txt -b jar.txt -x "$P" https://www.example.com/accountWhen curl works but your code doesn't
That's useful information: the proxy and target are fine, so the difference is in your client. Compare:
- Headers (use
-vin curl and log headers in your code). - TLS fingerprint (curl's differs from Python's or Node's).
- Proxy scheme (
socks5vssocks5h). - Environment variables your code might read.
- Connection reuse affecting rotation.
See Python requests proxies, Node.js proxies and common proxy errors.
Residential tip: Rayobyte gives you three ways to run this: raw residential or datacenter proxies for your own code, the Web Unblocker as a drop-in proxy endpoint for hard sites, or a Scraping API that handles browsers and retries. See Rayobyte for web scraping.
Logging every timing at once with %{json}
When you're comparing proxies or keeping records, -w '%{json}' prints all of curl's write-out variables as one JSON object: status, IPs, timings, sizes and more. That makes results easy to save and analyse:
curl -s -o /dev/null -x http://USER:PASS@gate.example.com:7777 \
-w '%{json}\n' https://example.com >> results.jsonlEach line in results.jsonl is one request. Fields worth looking at include http_code, remote_ip, time_connect, time_appconnect, time_starttransfer, time_total and size_download. With jq, a quick summary is one line:
jq -r '[.http_code, .time_total] | @tsv' results.jsonl | sort | uniq -c | sort -rn | headSome practical uses:
- Provider comparisons: run the same URL list through each provider and keep one JSONL file per provider.
- Regression checks: keep a baseline and compare after changing servers, regions or plans.
- Support tickets: a few lines of JSON with timestamps are far more useful to a provider than "it's slow".
Note that remote_ip is the address curl connected to, which is the proxy, not the exit IP; use an IP echo service for the exit. The everything curl guide to proxies covers the proxy options in depth. For fair speed comparisons, see how to test proxy speed.
If you use Webshare, our guide to Testing Webshare Proxies with cURL covers the setup, which Webshare product to choose and the mistakes to avoid.
If you're weighing Rayobyte as well, Rayobyte for Web Scraping explains which of its products fits, and Rayobyte vs Geonode vs Webshare puts it side by side with Geonode and Webshare.
Key takeaways
-xsets the proxy; credentials can go in the URL or in--proxy-user.- Use
socks5h://so DNS resolves through a SOCKS proxy. -vshows the CONNECT exchange and is the fastest way to tell proxy errors from target errors.- curl reads lowercase
http_proxyfor HTTP targets;HTTPS_PROXY,ALL_PROXYandNO_PROXYwork in either case. -wtiming variables give connect, TLS and time-to-first-byte measurements for quick speed tests.- If a request works in curl but not in your code, the problem is in your client configuration. See common proxy errors.
curl is ideal for testing, but full pages that rely on JavaScript need a browser; see our Puppeteer proxies guide. To choose the proxies you test, read the best proxies in 2026.
FAQ
Why does curl ignore my HTTP_PROXY variable?
curl only reads the lowercase http_proxy for plain HTTP. Use lowercase or pass -x.
How do I bypass the proxy for one request?
Use --noproxy '*' or set no_proxy.
Does curl support proxy chains?
Not directly. Use a tool like proxychains. See proxy chains.
Sources and further reading
Independent references that back up the points above, from standards bodies, governments, universities and non-profits. They open in a new tab.
- curl man page (curl project): The full curl manual, including the --proxy and --proxy-user options.
- SP 800-63B: Authentication and Authenticator Management (NIST): NIST's guidance on passwords and authentication, relevant to proxy credentials and accounts.
- Choosing the VPN That's Right for You (Electronic Frontier Foundation): The EFF's guide to what VPNs do and do not protect, which also applies to proxies.
- Proxy servers and tunneling (MDN Web Docs (Mozilla)): Mozilla's developer explainer on forward proxies, reverse proxies and tunneling.
- RFC 1929: Username/Password Authentication for SOCKS V5 (IETF / RFC Editor): How SOCKS5 proxies check a username and password.
Editorial note: Proxy providers change their pools, features and prices often, so treat any figures here as typical ranges at the time of writing and confirm current terms with the provider before you buy.