How to Check a Proxy: Reproducible Connectivity, Auth, IP, DNS and Protocol Tests

Proxyca team · 28 Nov, 2025 · Updated 30 Oct, 2026


How to Check a Proxy: Reproducible Connectivity, Auth, IP, DNS and Protocol Tests

A reliable proxy check is a short series of repeatable command-line requests, each answering one question: can you reach the proxy, does it accept your credentials, does the request pass through, which address does the destination see, and who resolved the hostname. Run the checks in that order and record the exact output of each, so a failure points to one layer instead of a vague "proxy not working".

This guide is provider-neutral and uses curl. Results depend on your curl version and build, so check what you have installed before you compare notes with anyone else. For endpoint formats, ports and supported protocols, use the documentation of your own proxy provider.

Quick checklist

  1. Set the proxy explicitly and rule out stray environment variables.
  2. Pick the correct scheme and state the port.
  3. Test authentication and read the status or method result.
  4. For HTTP proxies, see whether a tunnel is formed for HTTPS targets.
  5. For SOCKS5, classify any failure by its reply code.
  6. Compare local and proxy-side DNS resolution.
  7. Request an IP-echo endpoint through the proxy and compare it with a direct request.

Start with a clean test

Proxy settings can come from places you forgot about. According to the curl manual, proxy environment variables can be written in lower or upper case, and the lower-case version takes precedence. http_proxy is the exception: it exists only in lower case. The libcurl documentation adds that using a proxy environment variable has the same effect as the --proxy option, and that setting the proxy string to an empty string explicitly disables proxy use even when a variable is set.

So a clean test names the proxy on the command line every time, and a baseline request without a proxy is made deliberately rather than by accident. If a result looks odd, list your proxy-related environment variables first.

Pick the scheme and state the port

The curl manual explains that with no scheme or with http://, the value of --proxy is treated as an HTTP proxy. Prefixes select a specific SOCKS version. Always write the port yourself. The libcurl documentation advises against assuming any single port is widely used for proxies, so do not guess one for an HTTP proxy.

Scheme What curl does
http:// (or no scheme) Treats the value as an HTTP proxy
socks4:// Uses SOCKS4
socks4a:// Uses SOCKS4a; the proxy resolves the hostname
socks5:// Plain SOCKS5; the hostname is resolved locally
socks5h:// SOCKS5; the proxy resolves the hostname

The resolution notes follow the libcurl documentation, which says socks4a:// and socks5h:// make the proxy resolve the hostname and that socks5:// is plain SOCKS5, and the curl manual, which says --socks5 resolves locally. SOCKS5 is conventionally served on port 1080 according to RFC 1928, and curl assumes 1080 for --socks5-hostname when no port is given, but treat that as a convention and still write the port. For a comparison of the protocol versions themselves, see the article SOCKS4 vs SOCKS5: Authentication, DNS and UDP Compared.

A first connectivity test, with placeholders you replace:

curl --proxy 'http://PROXY_HOST:PROXY_PORT' -U 'USER:PASSWORD' 'http://ECHO_URL'

Check authentication

For an HTTP proxy, credentials go in -U / --proxy-user as user:password. If you embed them in the proxy string instead, curl URL-decodes them, so write @ as %40 and a colon as %3a. A password such as p@ss becomes p%40ss:

curl --proxy 'http://USER:p%40ss@PROXY_HOST:PROXY_PORT' 'http://ECHO_URL'

Basic is curl's default method with proxies. --proxy-anyauth lets curl pick a suitable method for an HTTP proxy, but the manual notes it can cost an extra request/response round trip.

RFC 9110 gives a way to separate two situations:

Response What the RFC describes What to check
407 with Proxy-Authenticate A proxy that requires authentication should answer this when credentials are missing, invalid or partial Username, password, encoding, offered scheme
403 Valid credentials that are not adequate for access ought to get this Which component returned it, then access rules

Every 407 the proxy generates must carry at least one Proxy-Authenticate header, so the offered scheme can be read from it.

A 403 needs one extra step. In forwarding mode, the response may come from the destination rather than the proxy. Before drawing any conclusion, confirm which side produced it. For an HTTPS target, the status line of the CONNECT response comes from the proxy. If the proxy itself returned 403 after accepting your credentials, look at its access rules rather than at a mistyped password. A 407 points at the credentials themselves.

For SOCKS5, authentication happens in two steps. The client sends a method-selection message, and if the server answers with method X'FF', none of the offered methods is acceptable and the client must close the connection. The defined methods are X'00' no authentication, X'01' GSSAPI and X'02' username/password. RFC 1928 says implementations should support username/password, so that method is a recommendation, not a guarantee for every server. In curl, --socks5-basic selects username/password and is enabled by default.

In the username/password step defined in RFC 1929, a status of X'00' means success; any other status is a failure and the server must close the connection. That RFC also states the password travels in cleartext, so the step is not recommended where sniffing is possible and practical. Authentication of this kind controls access to the proxy; it is not encryption of your traffic.

HTTP proxies: forwarding versus CONNECT

For an http:// target, the client sends the proxy an HTTP request whose target matches the destination URI; this is forwarding mode. For HTTPS targets a CONNECT request asks the proxy to open a tunnel. Per RFC 9110, the CONNECT target is only host:port and there is no default port, so the client must always send one. Any 2xx response means the tunnel is formed and both sides switch to tunnel mode right after the response headers. Any other response means no tunnel exists.

Two practical consequences:

  • Test both an http:// and an https:// URL through the proxy, and record the status the proxy returned for CONNECT. A success on plain HTTP says nothing about tunnelling.
  • A refused CONNECT is not always a fault. RFC 9110 says proxies supporting CONNECT should restrict it to a limited set of known ports or a configurable list of safe targets, so a refusal for a non-web port can be a policy outcome.

The curl manual also notes that operations over an HTTP proxy are converted to HTTP, so some protocol-specific operations may be unavailable unless you tunnel through the proxy. For more background on HTTPS proxies, see What Is an HTTPS Proxy and How Do SSL Proxies Work?.

SOCKS5: classify failures by reply code

When a SOCKS5 request fails, the REP field of the reply says why. RFC 1928 defines these among others:

REP Meaning Where to look first
X'00' Succeeded The proxy path works for this request
X'02' Connection not allowed by ruleset Rules applied by the proxy
X'03' Network unreachable Network reachability beyond the proxy
X'04' Host unreachable Reachability of the target host
X'05' Connection refused The target address and port
X'07' Command not supported Whether the server implements that command
X'08' Address type not supported Whether it accepts a hostname or an IP in that form

The request carries a command (CONNECT X'01', BIND X'02', UDP ASSOCIATE X'03') and an address type (IPv4 X'01', domain name X'03' or IPv6 X'04'), so the client can send either a hostname or an IP. If one form is rejected with X'08', try the other.

Compare DNS resolution

A reproducible way to see where a hostname is resolved is to run the same request with both schemes and compare:

curl --proxy 'socks5://PROXY_HOST:PROXY_PORT' -U 'USER:PASSWORD' 'http://ECHO_URL'
curl --proxy 'socks5h://PROXY_HOST:PROXY_PORT' -U 'USER:PASSWORD' 'http://ECHO_URL'

With socks5:// curl resolves the name on your machine; with socks5h:// the proxy does. If only one variant works, name resolution is one possible cause, but not the only one: socks5h:// sends a hostname, so the proxy's handling of that address type can also matter. Check the SOCKS5 reply code, for example X'08' for address type, before concluding. A matching result does not prove that nothing else on your system leaks queries; this test only distinguishes these two curl modes.

Use a current curl for socks5h:// tests. Advisory CVE-2023-38545 concerns hostnames passed to a SOCKS5 proxy for remote resolution, which can be at most 255 bytes, and recommends curl 8.4.0 or later. Check your installed version and build rather than assuming.

Measure the exit IP

Choose an IP-echo endpoint you trust, request it once directly and once through the proxy, and compare the two addresses. That request is the measurement. Do not read the address from the SOCKS reply: in a CONNECT reply, BND.ADDR and BND.PORT describe the address the server assigned for the target connection, and BND.ADDR often differs from the IP you used to reach the SOCKS server, so it is not a stand-in for what a destination sees. Treat the result as an observation about that one request.

What these checks cannot show

  • Ping and traceroute. SOCKS5 is a shim between the application and transport layers and does not forward ICMP, so those tools do not measure a SOCKS5 path.
  • UDP and WebRTC. UDP ASSOCIATE is a command a given server may or may not implement; it can answer with X'07'. RFC 8828 notes that HTTP proxies and most SOCKS proxies do not support UDP, so WebRTC falls back to TCP through the proxy. Test UDP-dependent behaviour separately.
  • Your curl build. Which options and proxy connection types are available depends on the version and build you run.

If the basic checks pass but a particular site still fails, the cause may be a response from the site rather than the connection. The article Why Your Proxy Is Not Working: Errors and Fixes covers separating connection errors, authentication errors and destination responses.

FAQ

Should I use socks5:// or socks5h://?

Run both. The first resolves hostnames locally and the second lets the proxy resolve them. Which one suits your application depends on where you need resolution to happen.

Why does my proxy refuse a connection to a non-web port?

Proxies that support CONNECT are advised to restrict it to known ports or a configurable list of safe targets, so a refusal can be policy rather than a malfunction.

Is a proxy password encrypted?

Not by the SOCKS5 username/password step: RFC 1929 sends it in cleartext. Whether anything else protects the connection depends on the setup you use.

Next step

When your checks give clear results and you want to choose a proxy service, Open Proxyca in Telegram.