Proxy Connection Refused — Causes and How to Fix Each One

Key takeaways

  • Connection refused means something answered — with a refusal. Your SYN was met by a TCP reset or an ICMP port-unreachable, so the host is reachable and nothing is accepting on that port.
  • Refused and timed out are opposite symptoms. A refusal is a fast, explicit no. A timeout is silence, which points at dropped packets, a wrong address or a firewall configured to discard rather than reject.
  • The wrong port is the most common cause by a wide margin — including using the SOCKS5 port for HTTP traffic, the HTTP port for SOCKS5, or the rotation endpoint's port for either.
  • A proxy URL with no explicit port inherits the scheme's default — 80 for http://, 443 for https:// — so a missing :30001 silently dials a port your proxy is not on.
  • https:// in front of a proxy host means "speak TLS to the proxy itself", which is not the same as proxying HTTPS traffic. Most commercial proxy endpoints are plain http:// even for HTTPS destinations.
  • A local proxy bound to 127.0.0.1 refuses every connection from any other machine. The process being up is not the same as it being reachable.
  • Isolate at the TCP layer first with nc -vz host port. If that fails, no amount of credential, header or client-library debugging can help you.

Connection refused is the most informative error a network stack produces, and almost nobody reads it that way. It is not a vague failure. It is a specific event: your machine tried to open a TCP connection, and something on the other end said no — immediately and explicitly.

That immediacy is the clue. A refusal means the packets arrived: DNS worked, routing worked, the host is up. What failed is far narrower than "the proxy is broken".

What "connection refused" actually means

Your client sent a TCP SYN to open a connection and received an explicit rejection instead of a handshake — normally a TCP RST packet, sometimes an ICMP port-unreachable message. The operating system surfaces that as ECONNREFUSED: errno 111 on Linux, 61 on macOS, 10061 on Windows. Two facts follow, and both narrow your search enormously.

The same event looks different in each client:

curl:    curl: (7) Failed to connect to proxy.example.com port 30001
                after 14 ms: Connection refused

Python:  requests.exceptions.ProxyError: ... [Errno 61] Connection refused

Node:    Error: connect ECONNREFUSED 203.0.113.10:30001

Note the timing in the curl line. Fourteen milliseconds is the signature of a refusal. If your failure takes ten or thirty seconds, you have a timeout instead, and the causes are different.

Refused, timed out, or reset? Read the symptom first

These three get reported as the same problem and they implicate completely different layers. Classify the failure before you touch any config — it takes seconds, costs nothing, and eliminates most of the candidate causes below on its own, before you have changed a single line.

SymptomWhat happened on the wireWhat it implicates
Connection refused (fast)Your SYN was answered with a TCP RST or ICMP unreachableNothing listening on that port, or a reject-policy firewall
Connection timed out (slow)Your SYN was never answered at allDrop-policy firewall, wrong IP, routing problem, host down
Connection reset (mid-stream)The session opened, then the peer tore it downYou reached the service; it accepted then dropped you
DNS resolution failureNo address was ever returnedHostname wrong, resolver broken, or an internal-only name
TLS handshake errorTCP connected, TLS negotiation failedSpeaking TLS to a plaintext port, or the reverse
HTTP 407The connection worked and the proxy repliedCredentials — see 407 Proxy Authentication Required

The bottom two rows matter because they are progress: a TLS error or a 407 both prove TCP succeeded, which rules out every cause on this page.

Cause 1: the wrong port, including the one you never typed

This is the most common cause and worth exhausting first. Providers hand out several ports per endpoint — one for HTTP, one for SOCKS5, often a separate one for the rotation API — and a port with no listener refuses instantly. The subtle version is a URL with no port, where the client substitutes the scheme's default.

http://proxy.example.com            → dials port 80    → refused
https://proxy.example.com           → dials port 443   → refused
http://proxy.example.com:30001      → dials port 30001 → correct

That is why the port in the error message is the first thing to read. If it says 80 or 443 and your proxy lives on a high port, you found the bug in one line.

Then check the explicit ones:

  1. Compare against the dashboard character by character. 30012 and 30021 look identical at a glance.
  2. Confirm the protocol matches the port. Many providers run SOCKS5 and HTTP on separate ports, and the other protocol's port simply is not open to you.
  3. Do not point traffic at the rotation endpoint. Rotation is frequently an HTTPS API on a different host and port entirely.
  4. Stay inside your assigned range. Multi-port setups allocate a block per customer.

Note the relationship with authentication: the wrong port refuses at the TCP layer, while wrong credentials on the right port return a 407.

Cause 2: https:// when the proxy speaks plain HTTP

The scheme in a proxy URL describes how you talk to the proxy, not what the proxy carries. http:// means a plaintext connection to the proxy, over which HTTPS destinations are tunnelled using CONNECT. https:// means open a TLS session with the proxy itself before saying anything at all.

Most commercial proxy endpoints want plain http:// even when every destination you fetch is HTTPS. Your traffic stays end-to-end encrypted inside the tunnel; the proxy only sees the hostname it was asked to reach.

Get it wrong and you get one of two errors: connection refused, when the wrong scheme also changed the default port, or a TLS handshake failure, when the port was explicit and the client attempted TLS against a plaintext listener. Same root cause, two faces. If your credentials were handed over as PROTOCOL IP:PORT:USER:PASS, the protocol field is authoritative.

Cause 3: the proxy is down, or listening somewhere else

If you run the proxy yourself — a local SOCKS tunnel, an inspection proxy, a self-hosted forwarder — a refusal usually means it is not listening where you think. Two separate failures look identical from outside: the process is not running, or it is running and bound to an interface you are not connecting from.

The binding case catches almost everyone. A service bound to 127.0.0.1 accepts connections only from the same machine, so every remote connection is refused while the process log shows a clean start. Bind to 0.0.0.0 for remote access, or use a tunnel.

ss -lntp | grep 30001                 # Linux: what is bound, and to which address
lsof -nP -iTCP:30001 -sTCP:LISTEN     # macOS: same question

The containerised variant: code inside a container pointing at 127.0.0.1:30001 is dialling the container's loopback, not the host's — so the connection is refused.

Cause 4: firewalls, ISPs and non-standard ports

A firewall produces either error depending on its policy. Reject sends a RST or ICMP unreachable and you see connection refused; drop discards silently and you see a timeout. So a refusal on a port you know is open points at a rejecting rule somewhere along the path rather than at the proxy.

Proxy ports usually sit in the high, non-standard range, which is exactly what restrictive networks filter:

One test settles it: connect from a completely different network, such as a phone hotspot with Wi-Fi off. If it works there and refuses at your desk, the problem is your egress policy, not the proxy.

Cause 5: IP allowlists that reject instead of challenging

Providers supporting IP-allowlist authentication have to decide what to do with an unrecognised source address. Some answer politely with a 407. Others close or never open the connection, which reaches you as a refusal — an authentication failure wearing a network error's clothes.

That is why refusals appear on configs that worked yesterday and were never edited. The address you leave from changed:

Check your current egress address against the allowlist before assuming anything is broken. If your workload has no stable egress address, allowlisting is the wrong auth mode and username/password is the fix.

Cause 6: IPv6 when nothing is listening on IPv6

If the proxy hostname resolves to both an A and an AAAA record, most clients try IPv6 first. When the proxy only listens on IPv4, that attempt is refused — sometimes before the client falls back cleanly. This is the usual explanation for "works on my laptop, refused on the server" when only one of the two has working IPv6.

curl -v -4 -x http://proxy.example.com:30001 https://api.ipify.org   # force IPv4
curl -v -6 -x http://proxy.example.com:30001 https://api.ipify.org   # force IPv6

If -4 works and -6 refuses, you have your answer: use the IPv4 literal, or disable IPv6 for that client.

Isolating it: netcat first, then curl

Test the layers in order, cheapest first. Each step either passes and hands you to the next or fails and tells you where to stop looking. Do not debug credentials, headers or client libraries until TCP connects — no header ever reaches a socket that was refused.

dig +short proxy.example.com          # 1. does it resolve, and to what?

nc -vz proxy.example.com 30001        # 2. does TCP open at all?
# succeeded → port is open, move on
# refused   → nothing listening, or a rejecting firewall
# timeout   → dropped packets; different problem, different page

# 3. run the same nc from a different network (phone hotspot, cloud shell)

curl -v -x http://user:[email protected]:30001 https://api.ipify.org   # 4.

At step four a 407 counts as success: TCP worked and you have reached authentication. A 403, a challenge page or a rate limit means the destination is answering.

When this becomes an infrastructure problem

Everything above is a configuration bug with a free fix, and that covers the overwhelming majority of refusals. The genuinely infrastructural version has a different shape: refusals that are intermittent, on a config nobody edited, clustered in time rather than spread evenly.

That pattern points at the proxy's lifecycle rather than your client — a device restarting, a connection cap reached, a backend rotating out from under a shared endpoint. Client-side retries paper over it without diagnosing it. Log the timestamp, host and port on every failure: if failures cluster, it is upstream.

This is one place the architecture behind the address genuinely matters. On a shared pool, connection capacity is shared with people you cannot see, so their load becomes your refusals — the same pooling dynamic that makes shared addresses inherit other customers' rate limits. On dedicated infrastructure a refusal concerns your device and your traffic. QuantumProxy runs one tenant per physical 4G/5G device, and publishes how rotation is verified rather than asking anyone to take it on trust. Wider trade-offs: mobile vs residential proxies.

The honest limitation: a real cellular device is a real radio on a real network, and radios have worse tail behaviour than a rack server. Carrier handovers, a tower issue, a device rebooting — physical events, and no architecture removes them. Dedicated hardware makes the failures yours, and therefore explainable; it does not make them impossible. Any provider claiming a mobile network never blips is describing a datacenter — and a datacenter address behaves like one, which is the entire reason people reach for mobile proxies.

The checklist, in order

Most refusals die at step one or four. Work top to bottom and stop at the first step that changes the symptom — each one either rules out a whole layer or hands you the answer outright, and none of them takes longer than a minute to run.

  1. Read the port in the error message. If it says 80 or 443 and your proxy is on a high port, your URL is missing an explicit port.
  2. Compare the port against the dashboard, including which port belongs to which protocol.
  3. Check the schemehttp:// in nearly all cases, even for HTTPS destinations.
  4. nc -vz host port. Refused is a TCP-layer problem; a timeout means this page is the wrong one.
  5. Try from a different network. This single test separates your egress rules from the proxy.
  6. Check your current egress address against any IP allowlist.
  7. Force IPv4 with -4 and see whether the refusal disappears.
  8. Only then debug credentials — and when a 407 replaces the refusal, that is real progress.

Frequently asked questions

What does ECONNREFUSED actually mean?

It means your machine sent a TCP SYN to open the connection and received an explicit refusal in return — normally a TCP RST packet, sometimes an ICMP port-unreachable message. The route worked and a host responded. The refusal says nothing is listening on that port, or that a firewall is configured to reject rather than silently drop. It is errno 111 on Linux, 61 on macOS and 10061 on Windows.

What is the difference between connection refused and connection timed out?

Refused is an answer; timed out is silence. A refusal comes back in milliseconds because something actively rejected the handshake, which means the host is up and routable. A timeout means your packets went unanswered until the client gave up, which points at a firewall that drops traffic, a wrong IP address, a routing problem or a host that is down.

Why does my proxy work in curl but get connection refused in my application?

Usually because the application is dialling a different address or port than you think. Common causes are a proxy URL without an explicit port so the scheme's default is used, an environment variable overriding your config, a container resolving localhost to itself rather than the host machine, or the client preferring IPv6 where nothing is listening. Compare the actual destination in each case before changing anything else.

Can a firewall cause connection refused rather than a timeout?

Yes. A firewall rule set to reject sends back a TCP reset or an ICMP unreachable, which surfaces as ECONNREFUSED. A rule set to drop discards the packet silently and surfaces as a timeout. Both are firewalls, and the difference between the two error messages tells you which policy is in effect somewhere on the path.

Should my proxy URL start with http:// or https://?

For most commercial proxy endpoints, http:// — even when the traffic you are sending is HTTPS. The scheme describes how you talk to the proxy, not what the proxy carries. HTTPS destinations are tunnelled with CONNECT over that plain connection. Writing https:// tells the client to open a TLS session with the proxy itself, which fails unless the proxy is specifically configured for it.

I get connection refused only sometimes. What causes that?

Intermittent refusals usually mean a service that restarts, a connection cap being hit, or a shared endpoint sending you to a backend that is temporarily out. A steady refusal is a configuration problem; an intermittent one is a capacity or lifecycle problem. Log the exact timestamp, host and port on every failure, because the pattern over time is what identifies it.

Dedicated mobile proxies, one dashboard

Real 4G/5G devices on US carrier SIMs. Sticky IP per customer, rotation on demand.

See plans