Diagnosing Proxy Connection Failures
Work up the stack (DNS, TCP, the CONNECT tunnel, then TLS) until the failing layer names itself. Covers firewalls, MTU and container networking.
There is a family of proxy problems in which the proxy never gets the chance to say anything at all. No error page, no status code, no response of any kind: the attempt either dies instantly with Connection refused or sits in silence until a timeout fires.
That silence is the whole diagnostic. If the proxy answered you, even with an error, the network path is healthy and you have a policy problem instead: a 407 means your credentials were rejected, which is a different guide entirely (fixing 407 errors), and a refusal from the destination website means the target is turning you away, covered in why your IP gets blocked. This guide is for the case where nothing answers.
A proxied HTTPS request is assembled in four layers, each standing on the one beneath it. The gateway hostname must resolve to an address. That address must accept a TCP connection on the right port. The proxy must open a CONNECT tunnel toward your target. And TLS must complete through the tunnel. When the connection never establishes, exactly one of those layers is failing, and testing them from the bottom up finds it in minutes. Testing from the top down (rewriting application code while the real problem is a firewall) can burn an afternoon.
Match the symptom to a layer
Before isolating anything, read what verbose output already tells you. Run the connection once with everything visible:
curl -v -x http://USERNAME:PASSWORD@HOST:PORT https://api.ipify.orgThe first line that goes wrong names the failing layer:
Could not resolve proxy: layer one. The hostname never became an address. Nothing after DNS was even attempted.Connection refused: layer two, and an oddly informative failure. A refusal is an active reply: your packet reached a machine, and the machine sent back a rejection. Either nothing is listening on that port, or something on the path rejects rather than drops. In practice this is usually a wrong port or a wrong host.- A long pause, then
Connection timed out: layer two with the opposite character. Your packets left and nothing at all came back. Something is silently discarding them: a firewall configured to drop, a dead address, or a route to nowhere. CONNECTis sent, then an error arrives: layer three. TCP worked, the proxy is speaking, and the tunnel request itself was refused or intercepted.TLS handshake, Client helloappears, then the output freezes: layer four, and almost always the MTU problem described below.- A
407status: stop; this is not a connection failure. The path works end to end and the proxy is asking about credentials.
Layer one: the hostname must resolve
Resolve the name yourself, through the same resolver your machine uses:
dig +short gw-rotating_shared.node4.io
# or, on systems without dig:
nslookup gw-rotating_shared.node4.ioStatic datacenter plans list a host for each proxy on the dashboard's Proxies page; gateway plans use the fixed gw-*.node4.io hostnames. Resolve whichever one you are actually connecting to; a surprising number of "DNS failures" are a hostname with a typo in it.
When resolution genuinely fails, three causes cover nearly every case. Corporate resolvers sometimes answer only for internal names and refuse or blackhole everything else. Containers carry their own resolv.conf, which can be stale or empty even while the host resolves fine. And an old entry in /etc/hosts (or the Windows equivalent) silently overrides DNS for that one name.
You can prove DNS is the only problem by taking it out of the path for a single request:
curl -v --resolve HOST:PORT:IP_ADDRESS -x http://USERNAME:PASSWORD@HOST:PORT https://api.ipify.orgIf the request succeeds with --resolve and fails without it, fix the resolver, not the proxy configuration.
Layer two: the port must accept a connection
Test raw TCP reachability with no HTTP involved:
nc -vz HOST PORT
# or, where netcat is not installed:
curl -v telnet://HOST:PORT --connect-timeout 5Interpret the outcome using the refused-versus-timeout distinction above, then act on it. For a refusal, re-check the host and port against the dashboard character by character: the rotating gateway's HTTP listener is port 8083, the premium tier is 8081, the residential gateway is 8082, and each SOCKS5 listener is a different port again (SOCKS5 setup lists them). Sending HTTP traffic to a host's SOCKS5 port, or connecting to yesterday's copied-and-pasted endpoint, produces exactly this symptom.
For a timeout, run the single most valuable test in this entire guide: try the same command from a different network. Tether your laptop to a phone hotspot and repeat it. If it succeeds over the hotspot and fails on your normal network, your machine, your account and the proxy are all fine; the network you are sitting on is filtering the traffic. That is the next section.
Corporate firewalls and egress filtering
Proxy ports are not web ports. A great deal of network security policy amounts to "outbound 80 and 443 are allowed, everything else is not". It is common on office networks, universities, hotels, guest Wi-Fi, and in cloud environments where a security group or egress rule was left at a restrictive default.
The signature is consistent: ordinary browsing works, the proxy times out, and the hotspot test succeeds. There is no client-side workaround for this, because the block is enforced by equipment you do not control. The fix is administrative: ask whoever runs the network to permit outbound TCP to the specific host and port you use. In a cloud VPC, you can add the destination to your instance's egress rules yourself. In Kubernetes, an egress NetworkPolicy can impose the same silence on one namespace while the node underneath connects freely.
Layer three: the CONNECT tunnel
For an https:// target, your client does not send the request to the proxy directly. It first asks the proxy to open a tunnel (CONNECT example.com:443), and the proxy answers HTTP/1.1 200 Connection established before any TLS begins. In verbose output you should see both lines.
If an error status arrives at this step instead, the proxy (or something claiming to be it) is reachable but declined the tunnel. A 407 here belongs to the credentials guide linked above. Anything stranger (an HTML block page, a certificate issued by a name you do not recognize, a redirect) usually means a middlebox on your network intercepted the CONNECT and answered in our place. Corporate TLS-inspection appliances do exactly this. The tell is in the certificate details curl -v prints: if the issuer is your employer's security vendor rather than a public certificate authority, your traffic is being intercepted before it ever leaves the building.
Layer four: TLS, and the MTU trap
The strangest failure mode looks like this: everything succeeds and Client hello is sent. Then nothing, forever, until a timeout. No refusal, no reset, no error.
This is the classic MTU black hole. Small packets travel fine, which is why DNS, TCP and the CONNECT all worked. The certificate exchange, though, arrives in full-size packets, and if any link on the path (a VPN, a PPPoE home connection, an overlay network) carries a smaller maximum packet size and the "fragmentation needed" signal is being blocked, those large packets are dropped without a trace. The handshake starts and simply never finishes.
Test for it by sending pings that refuse to be fragmented:
ping -M do -s 1472 HOST # Linux
ping -D -s 1472 HOST # macOSIf 1472 bytes fails but a smaller size like 1300 succeeds, you have found it. The clean fix is wherever the smaller link is: enable MSS clamping on the VPN or router. The pragmatic fix is to lower your interface MTU to 1400 and move on with your day.
The pool is IPv4
node4 endpoints publish IPv4 addresses, and the pool contains nothing else. On machines with a misconfigured dual-stack setup, a client can spend its entire timeout trying an address family that has no route before it ever attempts the one that works, or never fall back at all. Force the issue as a test:
curl -4 -v -x http://USERNAME:PASSWORD@HOST:PORT https://api.ipify.orgIf -4 fixes it, configure your client or resolver to prefer IPv4 for these hostnames rather than relying on fallback behavior.
Containers change every answer
A container has its own network namespace, its own resolver file, its own routes, and often its own proxy-related environment variables baked into the image. Every layer above can pass on the host and fail in the container, so establish which side is broken first:
docker run --rm curlimages/curl \
-v -x http://USERNAME:PASSWORD@HOST:PORT https://api.ipify.orgIf that works while your application container fails, compare the differences: an inherited HTTP_PROXY or NO_PROXY variable overriding your configuration, container DNS pointing somewhere dead (test with --dns 1.1.1.1), or host firewall rules applying to forwarded traffic. Overlay networks deserve special suspicion: many run a reduced MTU, which reproduces the hanging-TLS symptom from the previous section only inside the cluster, exactly where it is hardest to think clearly about.
The decision tree
Work it in order; each step assumes the ones above it passed.
- Run
curl -vthrough the proxy and note the first line that goes wrong. - Name will not resolve? Test with
--resolve. If that works, repair DNS: resolver config,resolv.confin the container, or a stale hosts-file entry. - Refused? Re-check host and port against the dashboard. Confirm you are not sending HTTP to a SOCKS5 listener or vice versa. Retest.
- Timeout? Hotspot test. Works elsewhere → egress filtering; take it to whoever administers the network or the cloud security group. Fails everywhere → open a support ticket from the dashboard with the verbose output and a
traceroute HOSTattached. - CONNECT answered with an error? A
407goes to the credentials guide. An unfamiliar certificate or a block page means interception on your side of the path. - TLS hangs? Run the ping test. Clamp the MTU or fix the VPN.
- curl succeeds but your application still cannot connect? The network is exonerated; the bug is in how the application passes proxy settings. The Python and Node.js guides cover the library-specific traps, and the curl converter will translate the exact command that just worked into the client library you are using, which removes the transcription step where most of these bugs are introduced.
Step one is easier if the command is right to begin with. The proxy connection builder assembles a correct curl invocation from a host, port, protocol and credential, and the rest of the free tools cover the neighboring checks: what address you are egressing from, and what headers you are really sending.
When the tree ends at a ticket, include the full curl -v transcript with the password redacted, say which networks you tested from, and paste the exact host and port. Those three facts usually turn a back-and-forth into a single reply.
If you are still evaluating rather than debugging a live plan, the features overview describes how the static products and the gateway endpoints differ; that is worth knowing before you decide which host you will be connecting to at all.