Proxy Error Codes Explained: Who Sent It and Who Fixes It

407, 403, 429, 502 and friends, split by which end of the chain sent them, with the first check to run for each before you touch anything.

A failed request through a proxy hands you three digits and no context, and the three digits are the least useful part. The useful fact, the one that decides everything you do next, is which machine produced them. A proxied request has two servers that can refuse it: the proxy in the middle and the target at the end. The same code can come from either, the fix for one side is wasted effort on the other, and nothing in the status line tells you which you are looking at.

This article is a routing table, not a deep dive. For each of the eight failures you will actually meet (407, 403, 429, 502, 503, 504, connection refused and connection reset), it says who emitted it, what it means, and the first check worth running. Where a failure deserves a full walkthrough, it links to one rather than repeating it.

Is this error coming from the proxy or from the target?

That is the first thing to settle, because the two want opposite responses and most wasted debugging time is spent fixing the wrong side.

An error from the proxy layer means something is wrong between you and us: credentials, endpoint details, account state, or the proxy's own path onward. Everything on that list is inspectable and changeable today, by you or by support, with no third party involved.

An error from the target means the site at the end of the chain received your traffic and declined it, or fell over while handling it. That is a negotiation with an organization that owes you nothing, and your levers are indirect ones: pace, exit type, headers, session behavior.

Misattributing the side is the classic time sink of proxy debugging: hours spent rotating credentials against what was a target-side block, or an afternoon spent "improving stealth" against what was a typo in a port number. Establish the side first. Everything downstream of that decision gets faster.

How do I tell whether the proxy or the target caused an error?

Change one variable at a time: swap the target and keep the proxy, then swap the proxy and keep the target. Whichever swap clears the error names the side.

Swap the target. Send a request through the same proxy to a neutral endpoint. https://api.ipify.org is convenient because it simply echoes the address it saw. If that succeeds, your credentials, your configuration and the proxy itself are all healthy, and the problem lives between the exit and your specific target. If it fails, stop thinking about the target entirely.

Swap the proxy. Fetch the target directly from your own connection, or through a different exit. If it fails from everywhere, the target is down or objecting to something that has nothing to do with proxies at all.

Two swaps give you a two-by-two matrix, and the cell that fails names the guilty side. Headers and bodies are useful supporting evidence: proxy-generated responses often carry a Via header or a recognizably templated body, and anti-bot pages are unmistakable HTML. But the swaps are conclusive and take about a minute.

One more habit worth building: look at the raw response, not your library's summary of it. Most HTTP clients wrap these failures in their own exception types: a Python requests script surfaces a refused proxy connection as ProxyError, Node reports the TCP-level failures as ECONNREFUSED or ECONNRESET, and several libraries retry silently before showing you anything. A single verbose curl of the same request shows you the actual status line, the actual headers and the actual body, which is the evidence the sections below ask about.

407 Proxy Authentication Required: the proxy, by definition

No origin website sends a 407; the code exists specifically so a proxy can challenge for credentials. Your request stopped at our edge and never went further, which narrows the cause to a short, local list: a credential belonging to a different product on your account, a password mangled by URL encoding, a whitelisted address that no longer matches where your traffic comes from, or an account that currently cannot authenticate at all. First check: one verbose curl through the proxy at a neutral URL, reading what was actually transmitted. Then work through fixing 407 Proxy Authentication Required top to bottom; it orders the causes by how often they actually occur, which beats guessing.

403 Forbidden: the target, almost always

The chain worked: the connection was made, the request was delivered, and the far end chose to refuse it. Web application firewalls, geographic fences and IP-reputation classifiers all answer with 403. First check: the same URL from your own home or office connection. If it loads there, the target is objecting either to the exit address or to the shape of your request. It is worth being candid that datacenter exits draw this classification more readily than residential ones, because datacenter ranges are published and trivially listed. Escalate in order of cost: fix the obvious header gaps, then try a different exit category, then read why is my IP getting blocked for the signal-by-signal diagnosis of what the target is keying on. One caveat before blaming the target: a proxy can also answer 403 when the destination itself is disallowed (a blocked port, for example), so if even neutral endpoints return it, re-run the swap test before going further.

429 Too Many Requests: the target, quoting its speed limit

The most honest error in this list: you asked too often and the target said so explicitly, instead of silently degrading you. Check for a Retry-After header and obey it literally. The decisive follow-up question is what the limit is keyed to. If it is keyed to the exit address, spreading load across more exits raises your ceiling, and the arithmetic for how many that takes is worked through in how many proxies do I need. If it is keyed to your account, API key or session cookie, more exits change nothing and pacing is the only real fix. Audit your own retry loop while you are here: a retry without backoff turns one 429 into a stream of them and can escalate a rate limit into a block.

502 Bad Gateway: the proxy speaking, about the target

A 502 is written by the proxy, but it describes a failure beyond it: the proxy reached out on your behalf and got a refused connection, a broken TLS handshake, or a response too malformed to relay. Responsibility is genuinely split: the messenger is ours; the cause is upstream. First check: does the target answer when fetched directly? Sporadic 502s are ordinary internet weather, and a retry with backoff absorbs them without drama. A persistent 502 confined to one target is more interesting: some sites drop classified exits at the TCP or TLS layer rather than answering politely, and through a proxy that surfaces as a 502 instead of a clean 403. Treat that case as a blocking investigation, not an infrastructure one.

503 Service Unavailable: either side; the body decides

Textbook meaning: the target is overloaded or under maintenance. Real-world complication: 503 is also the favorite status code of several anti-bot products, which serve their JavaScript challenge pages with it. So read the body before reacting. An HTML document full of obfuscated script is a bot defense engaging: a blocking problem, to be handled with the tools in the 403 section. A terse or empty body is genuine unavailability: a patience problem, to be handled with backoff and a later retry. A 503 originating from proxy infrastructure itself is possible but presents broadly, across many targets at once, rather than being confined to a single site.

504 Gateway Timeout: somebody upstream was too slow

The proxy connected onward, forwarded your request, and gave up waiting for the reply. Distinguish this from a client-side timeout before anything else: a 504 is a real HTTP response that arrived at your machine; a client timeout is your own software cutting the line, and the two have different culprits. Causes of a genuine 504 include a slow target, a long route, and deliberate tarpitting: some defenses serve suspected automation at a crawl rather than refusing it outright. First check: time the target directly. If it is slow for everyone, no proxy setting will help. If it is slow only through the chain, slow proxy speeds walks through isolating where the time is going.

Connection refused: no HTTP conversation ever started

There is no status code here because there was no HTTP: the TCP connection to the proxy's address and port was rejected outright. Nothing was listening where you knocked. The causes are unglamorous: a wrong port, a wrong hostname, a stale copy-paste, a protocol mismatch such as pointing an HTTP client at a SOCKS listener or the reverse (see SOCKS5 proxy setup for which is which), or a local firewall eating outbound connections. First check: compare the host and port in your configuration against the dashboard's Proxies page, copied rather than retyped. The systematic version of this hunt, layer by layer, is connection issues.

Connection reset: the line went dead mid-sentence

A reset differs from a refusal in its timing: the connection was established, something was in progress, and then one party, or a middlebox between them, tore it down. Corporate firewalls, national-level filtering, and target-side defenses that kill suspicious TLS handshakes all produce resets. The distribution of the resets carries the diagnosis. Resets on every destination point at your local network or your path to the proxy. Resets confined to one target, while neutral endpoints sail through the same proxy, point at that target objecting to the exit or to the handshake itself. The same connection issues guide covers capturing enough packet-level detail to tell the difference.

The triage sequence, condensed

  1. A 407 names its sender by definition. Skip the matrix and go straight to the 407 guide.
  2. Anything else: swap the target (neutral endpoint, same proxy).
  3. Then swap the proxy (same target, fetched directly).
  4. The failing cell of the matrix names the side; the section above names the first check; the linked deep guides carry the rest.

It is a boring procedure, which is the point. Boring procedures get followed at two in the morning, and this one converts "the proxy is broken", a statement that is unfalsifiable and unactionable, into a specific claim about a specific machine that a specific person can fix.

Two closing observations from the support queue. First, the majority of failures reported to us as proxy errors turn out to be target errors (403s and 429s), which no provider can make disappear by tuning infrastructure, and you should distrust any provider who claims theirs can. Second, when the matrix does point at the target, your two real levers are pacing and exit category. The pacing arithmetic lives in the sizing guide linked above; and where the diagnosis is that exits keep getting classified, rotating proxies change the economics of being blocked, because no single address stays around long enough to be precious. What no product changes is a determined target's willingness to defend itself. The codes above are how it tells you where the line is.