# Test proxy with curl: check exit IP, speed and errors

URL: https://cloudj.net/blog/test-proxy-curl
Published: 2026-11-11 · Updated: 2026-11-11

> Test proxy with curl in one command: HTTP and socks5h syntax, --proxy-user, checking the exit IP and country, timing each step, and reading common error codes.

Before you plug a new proxy into a scraper, a browser profile or a phone, it pays to test proxy with curl first. One command tells you whether the host, port and credentials are right, which IP the destination actually sees, and roughly how long each step of the connection takes. When something fails, curl's error messages point at the cause far more precisely than a browser does. This guide covers the commands for HTTP and SOCKS5 proxies, how to read the output, and a short troubleshooting table.

## The basic command to test proxy with curl

You need the four values from your provider: host, port, username and password. On Cloudj they are shown for each proxy in the [console](https://app.cloudj.net). The examples use `203.0.113.10` port `8080` as a placeholder.

For an HTTP proxy:

```bash
curl -x http://203.0.113.10:8080 --proxy-user myuser:mypass https://ifconfig.me/ip
```

- `-x` (long form `--proxy`) sets the proxy. The `http://` prefix tells curl it is an HTTP proxy.
- `--proxy-user` (short form `-U`) sends the proxy credentials. These are separate from `-u`, which authenticates to the destination site.
- `https://ifconfig.me/ip` is an IP echo service that returns the address it sees. Any similar service works.

If the proxy works, the output is the proxy's IP, not your own. Run the same URL without `-x` to compare.

You can also put the credentials in the proxy URL:

```bash
curl -x http://myuser:mypass@203.0.113.10:8080 https://ifconfig.me/ip
```

That form breaks when the password contains characters such as `@`, `:` or `#`, because they have meaning inside a URL. Either percent-encode them (`@` becomes `%40`) or keep using `--proxy-user`, which does not need encoding. Wrap the value in single quotes if it contains shell characters like `$` or `!`.

## Testing a SOCKS5 proxy: socks5 vs socks5h

For a SOCKS5 proxy, change the scheme:

```bash
curl -x socks5h://203.0.113.10:1080 --proxy-user myuser:mypass https://ifconfig.me/ip
```

The `h` matters. With `socks5://`, curl resolves the destination host name on your own machine and passes only the IP to the proxy. With `socks5h://`, the proxy resolves the name. Use `socks5h` when you want DNS lookups to happen at the proxy's location, which is usually what you want for geo-sensitive work and for keeping lookups off your local network. The long options `--socks5-hostname` and `--socks5` do the same thing if you prefer them. The difference between the two protocols is explained in [SOCKS5 vs HTTP proxy](https://cloudj.net/blog/socks5-vs-http-proxy).

A common mistake is pointing an `http://` proxy URL at a SOCKS5 port, or the reverse. The connection then fails with an unhelpful error. On Cloudj you can check which protocol an order uses, and switch it, in the console where the location supports both.

## Check where the IP appears to be

To see the country and network that IP lookup services assign to the proxy, query a service that returns JSON:

```bash
curl -s -x http://203.0.113.10:8080 --proxy-user myuser:mypass https://ipinfo.io/json
```

Geolocation databases are built independently and do not always agree, so a different service may show a different city. The country is usually consistent. If a target site disagrees with what you expected, it is using its own database. Lookup services also report the network type, for example whether an address belongs to a hosting range or to an ISP; the [datacenter vs static ISP guide](https://cloudj.net/blog/datacenter-vs-static-isp-proxy) explains why that matters.

## Measure timing step by step

curl can print how long each phase took. Save this as a reusable command:

```bash
curl -s -o /dev/null -x http://203.0.113.10:8080 --proxy-user myuser:mypass \
  -w 'connect: %{time_connect}s  tls: %{time_appconnect}s  first byte: %{time_starttransfer}s  total: %{time_total}s  code: %{http_code}\n' \
  https://example.com/
```

How to read it:

- `time_connect` is the TCP connection to the **proxy**, so it mostly reflects the distance between you and the proxy.
- `time_appconnect` includes the TLS handshake with the destination through the tunnel.
- `time_starttransfer` adds the destination's response time.
- `http_code` is the destination's status code.

Run it five or ten times and look at the spread rather than a single result. If you test from a server in the same region as your real workload (for example a [cloud server](https://cloudj.net/cloud-servers) near your target), the numbers reflect production better than tests from your laptop.

## See the full conversation with -v

When something fails, add `-v`:

```bash
curl -v -x http://203.0.113.10:8080 --proxy-user myuser:mypass https://example.com/ -o /dev/null
```

For an HTTPS destination through an HTTP proxy you should see curl send `CONNECT example.com:443`, then a line like `HTTP/1.1 200 Connection established`, then the TLS handshake. If the proxy answers `407 Proxy Authentication Required` instead, the credentials were rejected.

## Troubleshooting common errors

| What you see | Usual cause | What to check |
|---|---|---|
| `curl: (5) Could not resolve proxy` | Typo in the proxy host | Copy the host again from the console |
| `curl: (7) Failed to connect` | Wrong port, or a firewall blocks outgoing traffic to that port | Port number; try from another network |
| `407 Proxy Authentication Required` | Wrong username or password, or the password was rotated | Re-copy credentials; with an IP whitelist, check your current public IP |
| `curl: (28) Connection timed out` | Network path problem or the destination is slow | Add `--connect-timeout 10` to tell the two apart |
| `curl: (6) Could not resolve host` with `socks5://` | Your local DNS cannot resolve the name | Use `socks5h://` |
| SOCKS5 error saying the user was rejected | Wrong SOCKS credentials | Same checks as for 407 |
| Odd errors or empty reply | Protocol mismatch, HTTP URL on a SOCKS port or the reverse | Confirm the protocol in the console |

About IP whitelists: on Cloudj you can replace password authentication with a whitelist of up to 20 IP addresses. If the proxy uses a whitelist, run the test from a whitelisted machine and leave out `--proxy-user`. A test from any other IP will be refused, which is the intended behaviour. See [whitelist vs password authentication](https://cloudj.net/blog/proxy-authentication-whitelist-vs-password) for when to use which.

## Testing a list of proxies

If you ordered many IPs, a small loop checks them all. Put one `host:port:user:pass` per line in `proxies.txt`:

```bash
while IFS=: read -r host port user pass; do
  ip=$(curl -s --max-time 15 -x "http://$host:$port" --proxy-user "$user:$pass" https://ifconfig.me/ip)
  echo "$host:$port -> ${ip:-FAILED}"
done < proxies.txt
```

Every line should print its own proxy IP. A failure points to one specific proxy rather than a general setup problem.

## Notes for Windows and environment variables

On Windows 10 and 11, `curl.exe` is included. In Windows PowerShell type `curl.exe`, because plain `curl` may be an alias for a different command. Use double quotes instead of single quotes.

curl also reads proxy environment variables such as `https_proxy` and `ALL_PROXY`. For plain HTTP URLs it only reads the lowercase `http_proxy`. If a test behaves strangely, run `env | grep -i proxy` to make sure an old variable is not interfering. Full option details are in the official [curl manual](https://curl.se/docs/manpage.html).

## FAQ

### What does the -x option do in curl?

It sets the proxy to use for the request. The scheme in the proxy URL (`http://`, `socks5://`, `socks5h://`) tells curl which protocol to speak to the proxy.

### Should I use socks5 or socks5h?

Use `socks5h` in most cases so the proxy resolves host names. Plain `socks5` resolves names locally and sends only IP addresses through the proxy.

### Why does curl show my proxy IP but a website shows a different country?

Each site uses its own geolocation database, and databases sometimes disagree, especially at city level.

### Can I test a proxy without a password?

Yes, if the proxy uses an IP whitelist and you run curl from a whitelisted IP. Leave out `--proxy-user` in that case.

## Next steps

Once curl confirms the IP and credentials, you can move the same values into your browser, scraper or phone with confidence. If you still need proxies, the [dedicated proxy guide](https://cloudj.net/blog/dedicated-proxy-guide) covers how to choose, the [proxy overview](https://cloudj.net/proxy-ipv4) lists available countries, and the [pricing page](https://cloudj.net/pricing) shows live prices before you order in the console.
