Using cURL with a Proxy
A quick reference for proxying curl: HTTP and SOCKS5 syntax, credentials, environment variables, and verbose mode for diagnosing CONNECT failures.
- tutorials
- proxy-basics
curl is the fastest way to test a proxy without writing any code. One command tells you whether the endpoint works, what address it exits from and roughly how slow the hop is. That makes it the first tool to reach for when something is broken.
Basic HTTP proxy
curl -x "http://proxy.lightningbytes.com:1080" https://api.ipify.org
-x is shorthand for --proxy. The address printed is your exit IP, which is the check that matters.
With credentials:
curl -x "http://lb-USERNAME:SECRET@proxy.lightningbytes.com:1080" https://api.ipify.org
Two cautions. The password lands in your shell history, so prefer an environment variable. And if the password contains special characters, URL-encode it or use the --proxy-user flag instead.
curl --proxy "http://proxy.lightningbytes.com:1080" \
--proxy-user "lb-USERNAME:SECRET" \
https://api.ipify.org
SOCKS5
curl --socks5-hostname "proxy.lightningbytes.com:10003" https://api.ipify.org
The distinction between --socks5 and --socks5-hostname matters: --socks5-hostname sends hostnames to the proxy to resolve, so DNS happens on the proxy side. Plain --socks5 resolves locally, which leaks the lookup to your own resolver and can produce different results. Use --socks5-hostname unless you have a specific reason not to.
Environment variables
curl honours http_proxy, https_proxy and all_proxy, plus no_proxy for exclusions.
export https_proxy="http://lb-USERNAME:SECRET@proxy.lightningbytes.com:1080"
export no_proxy="localhost,127.0.0.1"
curl https://api.ipify.org
Be aware that these variables affect other tools too. A leftover https_proxy from debugging will route unrelated commands through your proxy, which is a confusing way to lose an afternoon. Unset them when you are done, and check environment variables when a tool behaves unexpectedly, as we note in What Is a Proxy Address.
Diagnosing with verbose mode
-v shows the connection stages, which is how you tell where a failure happened.
curl -v -x "http://proxy.lightningbytes.com:1080" https://api.ipify.org
What to look for:
CONNECT api.ipify.org:443followed by a success line means the tunnel was established.407during the CONNECT means the proxy rejected your credentials or does not recognise your source IP. That is a proxy problem, covered in Proxy Authentication.- Timeout during CONNECT usually means the wrong host or port, or a network path that cannot reach the proxy.
- Certificate errors after CONNECT point at TLS rather than the proxy itself.
The 407 versus 403 distinction is the single most useful diagnostic in proxy work, and it is worth internalising: 407 is the proxy, 403 is the target.
Measuring the latency the proxy adds
curl can report timings, which is a quick way to compare endpoints before committing to a workflow.
curl -o /dev/null -s -w "connect=%{time_connect} tls=%{time_appconnect} total=%{time_total}\n" \
-x "http://proxy.lightningbytes.com:1080" https://api.ipify.org
Compare that with the same request without -x to get the proxy-added delay. The LightningBytes proxy checker does the same pair of measurements and reports the exit IP at the same time, which is usually more convenient than assembling the flags.
Common mistakes
- Mixing the scheme and the protocol.
-x http://...reaches HTTPS destinations via CONNECT, which is correct. Using--socks5against an HTTP proxy port is not. - Forgetting the port. A correct hostname with the wrong port produces a connect timeout that looks like the proxy is down.
- Leaving credentials in history. Use
--proxy-userand an environment variable. - Ignoring
no_proxy, which causes local requests to be sent through the proxy unnecessarily. - Local DNS resolution with SOCKS5, which leaks lookups and can change results.
When curl is enough
For verifying an endpoint, testing credentials, comparing latency and reproducing a failure, curl is usually all you need. Once the endpoint works, move to your actual client, where the patterns are in Using Python requests with Proxies or Playwright Scraping with Proxies.
If curl works and your application does not, the problem is in the application's proxy configuration rather than the proxy, which is a useful thing to know before you change anything else.