# curl Proxy: Setup, Auth, SOCKS5 and Errors

> How to use a proxy with curl: the -x flag, proxy authentication, SOCKS5, environment variables, HTTPS tunnelling, and what each curl exit code means.

[Home](https://quanticdata.io/)/[Blog](https://quanticdata.io/blog/)/curl Proxy: Setup, Auth, SOCKS5 and Errors

# curl Proxy: Setup, Auth, SOCKS5 and Errors

ProxiesSep 9, 2026·10 min read·By [Aldo Morese](https://quanticdata.io/about/), founder of QuanticData

On this page [The curl proxy command in one line](/blog/how-to-use-a-proxy-with-curl/#the-curl-proxy-command-in-one-line) [curl proxy authentication](/blog/how-to-use-a-proxy-with-curl/#curl-proxy-authentication) [SOCKS5 with curl, and the one character that matters](/blog/how-to-use-a-proxy-with-curl/#socks5-with-curl-and-the-one-character-that-matters) [Setting the proxy once instead of on every command](/blog/how-to-use-a-proxy-with-curl/#setting-the-proxy-once-instead-of-on-every-command) [HTTPS through a proxy: CONNECT, and the certificate question](/blog/how-to-use-a-proxy-with-curl/#https-through-a-proxy-connect-and-the-certificate-question) [Reading the failure: curl exit codes with a proxy](/blog/how-to-use-a-proxy-with-curl/#reading-the-failure-curl-exit-codes-with-a-proxy) [What curl actually gets back, measured](/blog/how-to-use-a-proxy-with-curl/#what-curl-actually-gets-back-measured) [Rotating IPs from a curl loop](/blog/how-to-use-a-proxy-with-curl/#rotating-ips-from-a-curl-loop) [When to stop using curl](/blog/how-to-use-a-proxy-with-curl/#when-to-stop-using-curl)

To use a proxy with curl, pass `-x` (or `--proxy`) with the scheme, host and port, and `-U user:pass` when the proxy needs credentials. Everything else that goes wrong with curl and proxies is authentication, the SOCKS scheme, HTTPS tunnelling, or an exit code you have not read yet.

## The curl proxy command in one line

curl takes the proxy as an argument, not as configuration. This is the whole thing:

```
curl -x http://198.51.100.10:8080 https://example.com/
```

`-x` and `--proxy` are the same option. The value is a URL: `scheme://host:port`. Two defaults surprise people. If you leave out the scheme, curl assumes an HTTP proxy. If you leave out the port, curl uses 1080, which is the SOCKS port and almost never what your HTTP proxy listens on, so always write the port.

The proxy applies to every URL in that command, and only that command. Nothing is saved. To confirm the request really left through the proxy, ask an echo endpoint what IP it saw:

```
curl -x http://198.51.100.10:8080 https://api.ipify.org?format=json
```

If the JSON shows the proxy exit IP rather than your own address, the route works. If you want the same check without writing a command, the ../../tools/proxy-tester/ tool runs it in the browser and reports the exit IP, country and latency.

## curl proxy authentication

Most commercial proxies authenticate by username and password. curl accepts credentials in two places, and they are not equivalent.

```
curl -x http://gate.example.com:8080 -U myuser:mypass https://example.com/
curl -x http://myuser:mypass@gate.example.com:8080 https://example.com/
```

`-U` is short for `--proxy-user`. Inline credentials in the proxy URL do the same job, with one operational difference: the full command line, password included, is visible to anyone who can list processes on the machine and lands in your shell history. On a shared box or a CI runner, prefer `-U` with the value read from an environment variable, or put the proxy line in a config file with restrictive permissions.

Special characters have to be percent-encoded when the credentials sit inside the URL. A password containing `@` or `:` will split the URL in the wrong place and produce a name-resolution error rather than an auth error, which sends people hunting for the wrong bug.

When the proxy rejects the credentials it answers with HTTP 407, not 401. curl will print the status if you add `-v`. The full diagnosis of that status, including why a working username suddenly starts failing, is in ../how-to-fix-407-proxy-authentication-required/.

## SOCKS5 with curl, and the one character that matters

curl speaks SOCKS4, SOCKS4a, SOCKS5 and SOCKS5 with hostname resolution at the proxy. You pick with the scheme:

```
curl -x socks5://198.51.100.10:1080 https://example.com/
curl -x socks5h://198.51.100.10:1080 https://example.com/
```

With `socks5`, curl resolves the target hostname locally and sends the resulting IP to the proxy. With `socks5h`, the hostname travels to the proxy and is resolved there. The extra `h` is the difference between your local resolver seeing every domain you visit and the proxy seeing it. For scraping and for geo-targeted requests, `socks5h` is nearly always the one you want, because local resolution can also hand you an IP from the wrong region before the proxy ever gets involved. The long-form flags `--socks5` and `--socks5-hostname` do the same thing.

SOCKS5 carries any TCP traffic, not only HTTP, which is why it is the scheme of choice for tools that are not browsers. Our ../../socks5-proxies/ run on the same pools as the HTTP endpoints, so the choice is a protocol decision rather than a product one.

## Setting the proxy once instead of on every command

Three mechanisms exist, in increasing order of stickiness.

**Environment variables.** curl reads `http_proxy`, `https_proxy`, `all_proxy` and `no_proxy`. One quirk is worth memorising: `http_proxy` is honoured in lowercase only, while the others are read in either case. That rule exists because CGI environments turn an incoming `Proxy:` header into an uppercase variable, and curl refuses to be redirected by a remote header.

```
export https_proxy=http://gate.example.com:8080
export no_proxy=localhost,127.0.0.1,.internal.example.com
curl https://example.com/
```

**A config file.** curl reads `.curlrc` from your home directory on every invocation. A line such as `proxy = "http://gate.example.com:8080"` makes the proxy the default for every command, including commands run by scripts you forgot about. Run `curl -q` to ignore the file for one call.

**An alias.** A shell alias is the least surprising option because it only fires when you type that name, and it leaves plain `curl` untouched for everything else.

Whichever you pick, add the exceptions. `--noproxy` on the command line, or `no_proxy` in the environment, keeps localhost and internal hostnames off the proxy. Forgetting that is the usual cause of a health check that starts timing out the day someone exports a global proxy.

## HTTPS through a proxy: CONNECT, and the certificate question

When the target URL is HTTPS and the proxy is an HTTP proxy, curl does not send your request to the proxy in the clear. It issues a `CONNECT` request, the proxy opens a raw tunnel to the target on port 443, and the TLS handshake happens end to end inside that tunnel. The proxy sees the hostname and the byte counts, not the content. `-v` shows the CONNECT line and the handshake that follows it.

Two related flags get confused constantly:

- `-k` (`--insecure`) stops curl verifying the *target* server's certificate.

- `--proxy-insecure` stops curl verifying the certificate of an *HTTPS proxy*, meaning a proxy you speak TLS to.

If a certificate error appears only when the proxy is enabled, the proxy is almost certainly intercepting TLS and presenting its own certificate, which is normal for a corporate gateway and abnormal for a commercial scraping proxy. The correct fix is to trust that gateway's root certificate with `--cacert` or by installing it in the system store, not to reach for `-k`. Disabling verification hides a real man-in-the-middle from you as effectively as it hides the corporate one.

## Reading the failure: curl exit codes with a proxy

curl's exit code names the hop that broke. Reading it saves an hour of guessing, because several proxy failures produce identical-looking messages on screen.

| Exit | Name | What it means with a proxy set |
| --- | --- | --- |
| 5 | COULDNT_RESOLVE_PROXY | The proxy hostname does not resolve. A typo, a dead gateway name, or a malformed credential string that broke the URL. |
| 6 | COULDNT_RESOLVE_HOST | The target hostname does not resolve locally, which with `socks5` is your resolver failing, not the proxy's. |
| 7 | COULDNT_CONNECT | The proxy host resolves but refuses the TCP connection: wrong port, firewall, or an IP whitelist you are not on. |
| 28 | OPERATION_TIMEDOUT | The connection opened and then stalled. Common on residential exits when the target is slow or the exit dies mid-transfer. |
| 35 | SSL_CONNECT_ERROR | The TLS handshake failed inside the tunnel, often an intercepting proxy or a TLS version mismatch. |
| 56 | RECV_ERROR | The connection dropped while receiving. With a proxy this frequently means the CONNECT tunnel was closed by the gateway. |
| 97 | PROXY | The proxy handshake itself failed, which SOCKS proxies return when they reject the request outright. |

Add `-v` before you theorise, and use `--write-out` to make a script's output machine-readable:

```
curl -x http://gate.example.com:8080 -o /dev/null -s \
  -w 'status=%{http_code} time=%{time_total}\n' https://example.com/
```

Browser-side and library-side versions of the same failures are worth recognising too, since the same proxy misconfiguration shows up as ../err-tunnel-connection-failed/ in Chrome and as a ProxyError traceback in Python.

## What curl actually gets back, measured

curl retrieves HTML. It does not run JavaScript, so whether the data you want is in the response depends entirely on how the target renders. On 9 September 2026 we ran the ../../seo-audit/ API over six well-known pages from a US exit. Each URL was fetched twice, once as a plain HTTP client with no JavaScript and once fully rendered, and we counted the words each view produced.

| Page | Words without JS | Words rendered | Share visible to curl |
| --- | --- | --- | --- |
| Hacker News front page | 589 | 589 | 100% |
| Vercel home | 279 | 279 | 100% |
| Notion home | 225 | 228 | 99% |
| Walmart search, "laptop" | 1,009 | 4,273 | 24% |
| Airbnb search, Rome | 129 | 127 | shell only, both views |
| Zara US home | 0 | 557 | 0% |

Three of the six hand curl the complete page. One gives it a quarter. One returns an empty document that only becomes a page after scripts run. The Airbnb result is the interesting case: neither view contains the listings, because the search results live in a hydration JSON blob rather than in rendered text, so a browser would not have helped either. Reading that blob is cheaper and more reliable than rendering.

The practical rule: try curl first, look at the body, and only escalate when the data is genuinely missing. Escalation is not free, which is why our ../../web-scraping-api/ prices the plain fetch at $0.0002 per page and the JavaScript-rendered fetch at $0.001, five times more. Paying that on every URL when a fifth of your targets need it is the most common avoidable cost in a scraping budget.

## Rotating IPs from a curl loop

A single proxy IP running a loop of requests is the easiest pattern to block. Rotating pools solve this at the gateway: you keep one endpoint in your command and the exit IP changes per request, or stays fixed for a session when you ask it to.

```
for i in $(seq 1 5); do
  curl -s -x http://gate.example.com:8080 -U myuser:mypass \
    https://api.ipify.org?format=json
  echo
done
```

Run that against a rotating endpoint and you should see five different addresses. Against a sticky session you will see one, which is what you want when a target ties a cart or a login to an IP. Country selection is usually a flag inside the username rather than a separate host, so a curl command targeting Germany differs from one targeting Brazil by a few characters. Our ../../rotating-proxies/ start at $0.50/GB and ../../residential-proxies/ at $0.80/GB on the Basic line, with country targeting included rather than sold as an add-on.

Two habits keep a curl loop honest. Add `--retry 3 --retry-connrefused` so a single dead exit does not kill the run, and add a delay between requests. A shell loop can hammer a small site harder than a browser ever would, and the block you earn that way is not the proxy's fault.

## When to stop using curl

curl is the right tool for testing a proxy, reproducing a failing request, and pulling pages that render server-side. It stops being the right tool at three points: when the response needs JavaScript to become the page, when the target answers with a challenge instead of HTML, and when you need hundreds of URLs a minute with retries and structured output rather than a wall of markup.

At that point the choice is not curl versus a proxy, it is a raw fetch versus a managed one. A scraping API keeps the same request shape but adds rendering, retries and parsing behind one call, and bills per successful result. If you are still choosing the network underneath, ../residential-vs-datacenter-proxies/ covers which pool matches which target, and ../how-to-use-a-proxy-with-python-requests/ shows the same setup in Python once the shell prototype works. To move a working command into code, the ../../tools/curl-converter/ tool turns a curl line into Python, Node or Go.

### Sources & further reading

- [everything curl: HTTP proxy](https://everything.curl.dev/usingcurl/proxies/http.html)

- [everything curl: proxy environment variables](https://everything.curl.dev/usingcurl/proxies/env.html)

- [curl manual page: --proxy, --proxy-user, --socks5-hostname](https://curl.se/docs/manpage.html)

- [libcurl error codes](https://curl.se/libcurl/c/libcurl-errors.html)

- [CURLOPT_PROXY](https://curl.se/libcurl/c/CURLOPT_PROXY.html)

## FAQ

Quick answers on curl proxy.

[Something else? Ask us →](mailto:hello@quanticdata.io)

### How do I set a proxy in curl?

Pass `-x` or `--proxy` with a full proxy URL: `curl -x http://host:port https://example.com/`. Include the scheme and the port. Without a scheme curl assumes an HTTP proxy, and without a port it uses 1080, which is rarely correct for an HTTP gateway.

### How do I pass a username and password to a curl proxy?

Use `-U user:pass` (short for `--proxy-user`), or embed the credentials in the proxy URL as `http://user:pass@host:port`. The `-U` form is safer on shared machines because the inline form leaves the password in your shell history and in the process list. Percent-encode any `@` or `:` in the password.

### What is the difference between socks5 and socks5h in curl?

With `socks5://` curl resolves the target hostname on your machine and sends the IP to the proxy. With `socks5h://` the hostname is sent to the proxy and resolved there. Use `socks5h` when you do not want your local resolver to see the target, or when local resolution would return an IP for the wrong region.

### Why does curl fail with a certificate error only when the proxy is on?

The proxy is intercepting TLS and presenting its own certificate, which is standard for corporate gateways. Trust that gateway root with `--cacert` or install it in the system store. Using `-k` works but disables verification for every certificate, including a genuine attack. `--proxy-insecure` is a different flag: it skips verification of an HTTPS proxy, not of the target.

### How do I make curl ignore the proxy for some hosts?

Use `--noproxy` on the command line, or set the `no_proxy` environment variable to a comma-separated list such as `localhost,127.0.0.1,.internal.example.com`. Do this whenever you set a global proxy, otherwise internal health checks and localhost calls start routing through the gateway and timing out.

### Can curl scrape a JavaScript site through a proxy?

No. curl returns the HTML the server sends and never executes scripts. In our 9 September 2026 test of six pages, three returned their complete text to a plain HTTP client, one returned about a quarter of it, and one returned an empty document. Check the body first, and only pay for rendering on the targets that actually need it.

## Test the command against a real pool

Every account gets $2 of API usage free each month, and failed requests are never billed. Point a curl command at a rotating residential endpoint and read the exit IP back before you commit to anything.

[Start free — $2/month included](https://quanticdata.io/signup/)[Explore Residential Proxies from $0.80/GB](https://quanticdata.io/residential-proxies/)

## Related reading

[Proxies How Much Proxy Data Do I Need? Real Numbers Proxy plans are sold by the gigabyte and nobody tells you how many pages that is. We fetched 11 major pages and recorded what they cost on the wire: 47 KB to 302 KB compressed for the HTML, against 2.5 to 2.9 MB for a full browser load. The formula that turns pages per month into GB, three worked examples, the break-even where per-page pricing beats per-GB, and the settings that cut usage by five to twenty times. Read →](https://quanticdata.io/blog/how-much-proxy-data-do-i-need/) [Proxies Residential vs Datacenter Proxy: Which to Buy Residential and datacenter proxies differ in one fact the target can look up in a millisecond: the network the IP belongs to. Everything else, speed, price, block rate, follows from that. What the label means, a table that compares them honestly, a 100-request test that tells you which one your target requires, the cost-per-successful-page math, and when ISP or mobile is the right third answer. Read →](https://quanticdata.io/blog/residential-vs-datacenter-proxies/) [Proxies Scrapy Proxy Middleware: What Actually Runs Scrapy already ships a proxy middleware. Reading its source explains most 407s, most silent rotation bugs, and why a spider can return zero items with every response at HTTP 200. Read →](https://quanticdata.io/blog/scrapy-proxy-middleware/)

## Also on this site

Quantic**Data**

Residential proxies & web data APIs for AI.

#### Proxies

- [Residential Basic](https://quanticdata.io/residential-proxies/#basic)

- [Residential Premium](https://quanticdata.io/residential-proxies/#plans)

- [Cheap Residential](https://quanticdata.io/cheap-residential-proxies/)

- [Mobile Proxies](https://quanticdata.io/mobile-proxies/)

- [Datacenter Proxies](https://quanticdata.io/datacenter-proxies/)

- [ISP Proxies](https://quanticdata.io/isp-proxies/)

- [Rotating Proxies](https://quanticdata.io/rotating-proxies/)

- [Sneaker Proxies](https://quanticdata.io/sneaker-proxies/)

- [SOCKS5 Proxies](https://quanticdata.io/socks5-proxies/)

- [IPv6 Proxies](https://quanticdata.io/ipv6-proxies/)

- [Proxy locations](https://quanticdata.io/proxies/)

#### Data APIs

- [MCP Server](https://quanticdata.io/mcp-server/)

- [Web Scraper API](https://quanticdata.io/web-scraping-api/)

- [SERP API](https://quanticdata.io/serp-api/)

- [Collectors](https://quanticdata.io/collectors/)

- [Web Data for AI](https://quanticdata.io/web-data-api-for-ai/)

- [Quantic AI](https://quanticdata.io/ai-web-scraping-service/)

- [Crawl & Map](https://quanticdata.io/crawl-map/)

- [SEO Audit](https://quanticdata.io/seo-audit/)

#### Use cases

- [Company data](https://quanticdata.io/scrape-company-data/)

- [Price monitoring](https://quanticdata.io/competitor-price-monitoring/)

- [Market research](https://quanticdata.io/market-research-data/)

- [Real estate data](https://quanticdata.io/real-estate-data-scraping/)

- [Scrape job postings](https://quanticdata.io/scrape-job-postings/)

#### Company

- [Documentation](https://quanticdata.io/docs/)

- [Blog](https://quanticdata.io/blog/)

- [Free tools](https://quanticdata.io/tools/)

- [Partners](https://quanticdata.io/partners/)

- [About](https://quanticdata.io/about/)

- [Alternatives](https://quanticdata.io/alternatives/)

- [Pricing](https://quanticdata.io/pricing/)

- [FAQ](https://quanticdata.io/#faq)

- [For AI agents](https://quanticdata.io/#ai)

#### Free tools

- [All tools](https://quanticdata.io/tools/)

- [Website to Markdown](https://quanticdata.io/tools/website-to-markdown/)

- [PDF to Markdown](https://quanticdata.io/tools/pdf-to-markdown/)

- [WAF detector](https://quanticdata.io/tools/waf-detector/)

- [AI visibility audit](https://quanticdata.io/tools/ai-visibility-audit/)

- [AI crawler checker](https://quanticdata.io/tools/ai-crawler-checker/)

- [robots.txt tester](https://quanticdata.io/tools/robots-txt-tester/)

- [robots.txt generator](https://quanticdata.io/tools/robots-txt-generator/)

- [User agent](https://quanticdata.io/tools/user-agent/)

- [cURL converter](https://quanticdata.io/tools/curl-converter/)

- [Proxy tester](https://quanticdata.io/tools/proxy-tester/)

© 2026 QuanticData ·

- [quanticdata.io](https://quanticdata.io/)

·

- [Terms](https://quanticdata.io/terms/)

·

- [Privacy](https://quanticdata.io/privacy/)

If you are an AI agent:

- [llms.txt](https://quanticdata.io/llms.txt)

·

- [llms-full.txt](https://quanticdata.io/llms-full.txt)

---

Source: https://quanticdata.io/blog/how-to-use-a-proxy-with-curl/ · Site index for AI: https://quanticdata.io/llms.txt · Full dump: https://quanticdata.io/llms-full.txt
