Guide

Proxy Error Codes: What Each Message Means and Who Sent It

CONNECT tunnel failed, Unable to tunnel through proxy, ERR_TUNNEL_CONNECTION_FAILED, 403, 407, 502, 504: which side sent each proxy error, measured in nine clients.

HProxy Team··Updated September 27, 2026·16 min read
HProxy.Guide

Skip the dead lists.

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump.

Open the free proxy list→

Every proxy error comes from one of three places. Your own machine could not reach the proxy. The proxy answered, but would not or could not reach the site. Or the site answered through the proxy and refused. The number in the message does not tell you which, because a 403 or a 502 can come from the proxy or from the site. The words around the number do.

On 27 September 2026 we built a lab on one machine: a site, a proxy that fails on purpose, and three broken proxies. We ran the same three commands against 12 failures and one setup that works. Then we sent five proxy answers to nine clients, each case twice. This page shows what every client printed, and how to read it.

Three places a proxied request can fail

Who sent the error
  1. Your machine

    cannot reach the proxy: no answer at all

  2. The proxy

    answers the tunnel request with a code: 403, 407, 502, 504

  3. The site

    answers through the open tunnel: 403, 429, a check page

Source: HProxy lab, 27 September 2026

For an https:// site, your client first asks the proxy to open a tunnel, with a CONNECT request. The HTTP standard is exact about the answer. A 2xx code means the tunnel is open, and "Any response other than a successful response indicates that the tunnel has not yet been formed" (RFC 9110).

So any code that comes back in answer to CONNECT is the proxy speaking, and the site has not seen your request yet. That one rule sorts most proxy errors.

The one-minute triage

Run these three commands before you change a setting:

# 1. Does the site answer at all, with no proxy?
curl -s -o /dev/null -w '%{http_code}\n' https://your-site.example

# 2. Does the proxy work? This endpoint echoes the address it sees.
curl -s -x http://USER:PASS@HOST:PORT https://api.ipify.org

# 3. What happens on the way to your site?
curl -sv -o /dev/null -x http://USER:PASS@HOST:PORT https://your-site.example

On Windows, write -o NUL. Command two proves the address, the port, the login and the tunnel in one request. It also prints the exit address, which is the address every site judges.

Read command three from the top. The line CONNECT tunnel established marks the moment the proxy opened the way. A status line before it is the proxy's answer. A status line after it is the site's answer.

We ran the three commands against 13 setups: 12 failures we built on purpose, and one that works.

Terminal output of our lab: 13 setups, with the result of the direct request, the echo through the proxy, and curl -v through the proxy. Proxy failures show as "proxy answered 403, 407, 502 or 504"; site refusals as "tunnel, then site 403 or 429"; a check page as "tunnel, then site 200, not the page".
Our lab on 27 September 2026, with curl 8.21.0. The proxy's exit address was 127.0.0.2, and every site saw that address, not ours.

Four patterns cover every failure but one, the check page, which all three commands report as a success:

1. Direct2. Echo3. Through the proxyWhat broke
worksfailsfailsYour machine to the proxy, or the login
worksworksthe proxy answered a codeThe proxy could not or would not reach that site
worksworksthe tunnel opened, the site answered a codeThe site refused the proxy's address
failsworksthe proxy answered 502 or 504The site is down for everyone

Commands one and two alone cannot tell the second row from the third. In our lab, a site that answers you but not the proxy looked exactly like a site that blocks the proxy, until curl -v showed a 502 Bad Gateway from the proxy itself, before any tunnel opened.

One proxy answer, nine messages

Every client words the same event in its own way. We made our lab proxy refuse the tunnel with a 502, the answer for a site it cannot reach, and recorded each client:

  • curl 8.21.0: curl: (7) CONNECT tunnel failed, response 502
  • curl 8.16.0: curl: (56) CONNECT tunnel failed, response 502
  • git 2.51.2: fatal: unable to access 'https://intranet.lab.test/repo.git/': CONNECT tunnel failed, response 502
  • Python requests 2.32.3: ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 502 Bad Gateway'))
  • Python urllib: <urlopen error Tunnel connection failed: 502 Bad Gateway>
  • Java 17, HttpURLConnection: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 502 Bad Gateway"
  • Java 17, HttpClient: Tunnel failed, got: 502
  • PowerShell 7.6: The proxy tunnel request to proxy 'http://127.0.0.1:<port>/' failed with status code '502'."
  • Chrome 153: net::ERR_TUNNEL_CONNECTION_FAILED

The stray quote mark at the end of the PowerShell line is really there: it sits in the .NET message text itself. Two more clients, read in their source code rather than run. Node.js fetch with the ProxyAgent of undici gives Proxy response (502) !== 200 when HTTP Tunneling as the cause of its error. Programs written in Go keep only the words of the status line, here Bad Gateway, inside whatever message the program adds.

Older curl said it differently. Up to 7.86.0 the line read Received HTTP code 502 from proxy after CONNECT, and Stack Overflow questions with hundreds of thousands of views still quote it. curl 7.87.0 changed the wording to CONNECT tunnel failed, response 502, and 8.20.0 changed the exit code from 56 to 7.

A 403 and a 504 from the proxy came through the same way, with only the code and its name changed. A 407 did too, with two exceptions: both Java clients returned the status 407 without an error, and headless Chrome showed ERR_INVALID_AUTH_CREDENTIALS. The 407 guide covers the login cases.

A proxy that reads the request and hangs up, with no answer at all, produced other words again:

  • curl: Proxy CONNECT aborted, exit code 56, and git the same words in its unable to access line;
  • Python: Remote end closed connection without response;
  • Java: Unexpected end of file from server and HTTP/1.1 header parser received no bytes;
  • PowerShell 7: An error occurred while sending the request.;
  • Chrome: ERR_EMPTY_RESPONSE.

What the code means when the proxy sends it

The proxy chooses the number in CONNECT tunnel failed, response 503, and proxies do not all choose alike. What the standards and the most used proxy software say:

Code from the proxyWhat it means there
400, 404, 500Some proxies report a failed name lookup this way. Firefox shows these as a site it cannot find.
403Rules on the proxy refuse that site or port. Squid by default opens tunnels to port 443 only. Apache answers Connect to remote machine blocked.
407The proxy wants a login. See the 407 guide.
429A rate limit on the proxy, not on the site.
502The proxy could not connect to the site. Apache also uses it for DNS lookup failure for: a name.
503The proxy could not forward the request. Squid uses it for its error ERR_CANNOT_FORWARD.
504The proxy ran out of time while connecting to the site.
464 to 467, 568Codes of our own gateway, explained at the end of this page.

RFC 9110 defines 502 as a gateway or proxy that "received an invalid response from an inbound server", and 504 as one that "did not receive a timely response from an upstream server". Both describe the trip from the proxy onward. The fixes for each are in 502 through a proxy, 503 through a proxy and 504 through a proxy.

In a browser

Browsers show fewer details than the command line, and each has its own words.

Chrome's error page for a proxy it cannot reach: No internet, There is something wrong with the proxy server, or the address is incorrect, and ERR_PROXY_CONNECTION_FAILED.
Our own Chrome 152 on 2 September 2026 with --proxy-server pointed at a closed port: the browser never reached the proxy.
  • There is something wrong with the proxy server (Chrome and Edge, ERR_PROXY_CONNECTION_FAILED): the browser could not connect to the proxy at all. A note in the Chromium code says it does not cover failures of the CONNECT step. See there is something wrong with the proxy server and the Chrome fixes.
  • ERR_TUNNEL_CONNECTION_FAILED: the proxy answered the tunnel request with anything but 200 or 407. Chrome drops the answer "to avoid letting the proxy impersonate the target", in the words of its source code. See ERR_TUNNEL_CONNECTION_FAILED.
  • ERR_EMPTY_RESPONSE: in our lab, the proxy hung up without an answer.
  • ERR_TIMED_OUT or ERR_CONNECTION_TIMED_OUT: nothing answered in time. See the timeout guide.
  • A sign-in box, or ERR_INVALID_AUTH_CREDENTIALS in headless Chrome: the proxy wants a login. See the proxy sign-in box that keeps coming back.
  • Waiting for proxy tunnel... as the status text while a page loads: Chrome is still waiting for the proxy to open the tunnel. If it stays there, look at the proxy, not the site.

Firefox maps each code from a proxy to a page of its own. The proxy server is refusing connections covers a refused connection, and also a proxy that answered the tunnel with 403, 407 or 429 (refusing connections). Unable to find the proxy server means the name of the proxy did not resolve. A 502 from the proxy shows as Unable to connect, a 504 as The connection has timed out, and a 400, 404 or 500 as a site Firefox cannot find.

On an http:// address the rules change. There is no tunnel, the proxy fetches the page itself, and the browser can show the error page of the proxy itself. In our lab, Chrome showed the 502 and 504 pages of our proxy word for word. That is where proxy pages such as "The requested URL could not be retrieved" from Squid appear.

Windows has one more message of its own, could not automatically detect this network's proxy settings, with its own guide.

Error pages from a gateway: Apache, nginx and Squid

Some error pages come from a server that sits in front of a site and passes requests on to it. The HTTP standard calls it a gateway, or reverse proxy. Its wording names the software:

  • Apache: "The proxy server could not handle the request", with a "Reason:" line under it. Its 502 page says "The proxy server received an invalid response from an upstream server", and its 504 page "The gateway did not receive a timely response from the upstream server or application". See invalid response from upstream server.
  • nginx: "502 Bad Gateway" or "504 Gateway Time-out" in large type, with "nginx" under a line.
  • Squid: "ERROR: The requested URL could not be retrieved", then the cause, such as "The remote host or network may be down" or "Access control configuration prevents your request from being allowed at this time."

On an https:// site, such a page is not an answer from your proxy to the tunnel request, because Chrome and Firefox never show one. It came from beyond the tunnel: the site, or a device on your network that inspects encrypted traffic. On an http:// address through a proxy, it may come from your proxy, and the software name tells you which.

In a terminal or in code: before the proxy answers

These errors mean no answer came from the proxy at all. The problem is the address, the port, the network, or a dead proxy.

  • curl: (5) Could not resolve proxy: the name of the proxy does not exist. See curl error 5 and 97.
  • curl: (7) Failed to connect: nothing answered at the proxy address. curl 8.21.0 names the site first, as in Failed to connect to site.lab.test:443 over proxy 127.0.0.1: the address after "over proxy" is the one that did not answer. Since 8.20.0, exit code 7 also covers a refused tunnel, so read the words.
  • curl: (28) Connection timed out: in our lab, a proxy that accepted the connection and never answered.
  • curl: (56) Proxy CONNECT aborted: the proxy hung up. An http:// address pointed at a SOCKS port does the same.
  • curl: (97): a SOCKS handshake failed. See curl error 97 and SOCKS5 errors.
  • In Python, Cannot connect to proxy. wraps both a refused tunnel and a hang-up, so read the error inside it. See pip proxy errors.
  • Go programs report a proxy they cannot reach as proxyconnect tcp: followed by the network error. See Docker proxy errors.

The same errors have their own pages for curl, git, npm, Java, Node.js, C# and .NET, Scrapy and Puppeteer, Playwright and Selenium.

A dead proxy gives the same errors, and free proxies die fast. Of the 589,918 free proxies our engine had found by 2026-08-11, 4,023 were answering. Our free proxy list comes from the same engine, and the proxy checker tests any single proxy before you look anywhere else.

When the site answered

Once the tunnel is open, every status comes from the site, and it is a decision about the address it sees. In our lab, the echo endpoint saw 127.0.0.2, the exit address of the proxy. So did the sites that answered 403 and 429.

  • 403 Forbidden after the tunnel opened: the site refused that address. See 403 through a proxy and why an IP gets blocked.
  • 429 Too Many Requests: the site counted too many requests from that address. The standard lets it add a Retry-After header saying how long to wait (RFC 6585). See 429 through a proxy.
  • 200 OK with the wrong page: our check site sent the address of the proxy a "verify you are a human" page with a 200. Only a check on the content caught it: the page lacked the text the real page carries.

Block pages name the service that made the decision, and each has its own guide:

No proxy setting changes a decision the site has already made. Timeouts, logins and ports all belong to the first two legs.

Certificate errors

curl: (60) and ERR_CERT_AUTHORITY_INVALID mean a certificate did not verify. Through an ordinary HTTP proxy, the encrypted connection runs from your client to the site, inside the tunnel. The certificate belongs to the site, or to a device on your network that inspects encrypted traffic. Only an https:// proxy address adds a second certificate, that of the proxy itself, and the curl option --proxy-insecure skips the check of that one alone. See ERR_CERT_AUTHORITY_INVALID through a proxy and HTTP against HTTPS proxies.

Errors that come and go

A rotating proxy can give each request a new exit address. A site that tied a login, a cart or a page of results to the first address then sees a stranger, and may answer the next step with a 401, a 403 or a check page. If an error appears only on multi-step work, hold one address for the whole flow: see sticky against rotating sessions.

The lookup table

Each message links to the guide that covers it; the rest are covered above.

MessageWho sent it
There is something wrong with the proxy server, ERR_PROXY_CONNECTION_FAILEDyour machine: the proxy did not answer
Unable to find the proxy server, curl: (5) Could not resolve proxyyour machine: the proxy name
curl: (7) Failed to connect ... over proxyyour machine: the proxy port
Proxy CONNECT aborted, ERR_EMPTY_RESPONSEthe proxy hung up
The proxy server is refusing connectionsa refused port, or the proxy refused the tunnel
CONNECT tunnel failed, response 407the proxy wants a login
CONNECT tunnel failed, response 403rules on the proxy
response 502 or 504, Unable to tunnel through proxy, Tunnel connection failed (502, 504)the proxy could not reach the site
ERR_TUNNEL_CONNECTION_FAILEDthe proxy refused the tunnel
The proxy server could not handle the requestan Apache gateway
403 or 429 after the tunnel opened (403, 429)the site
200 with a check pagethe site
curl: (60), ERR_CERT_AUTHORITY_INVALIDthe certificate of the site, or a device on your network

If the proxy is ours

Our Residential Premium gateway answers a tunnel it cannot open with its own codes, so CONNECT tunnel failed, response 466 has an exact meaning on our lines:

CodeMeaning on our gateway
407The user name or password on the line is wrong, or the line belongs to another plan.
403A targeting part the gateway does not accept, such as a misspelt place.
464The target host, port or protocol is blocked by the usage policy of the network.
465No free address matches the targeting right now.
466The gigabytes of the plan are used up.
467A single session reached a traffic cap set on it.
568One sticky session failed; a new session id gets a fresh address.

The fix for each is in our error codes. To test any proxy, ours or not, the proxy checker shows whether it answers, its anonymity, the exit country and the network behind the address. Residential Lite starts at $0.44 per GB, and purchased gigabytes have no scheduled expiry date (residential proxies).

How we tested

On 27 September 2026 we ran one lab on a Windows 11 machine, twice. A lab site answered under eight names that exist nowhere else, over HTTP and over HTTPS with a certificate from a lab authority. Its answer depended on the name and on who asked: the normal page, an echo of the address of the caller, a 403, a 429 or a check page for the address of the proxy, a refused connection, or no answer at all.

The lab proxy wanted a login, opened tunnels to port 443 only, and answered 502 when its connection to the site was refused. A second copy wanted no login. Both connected to sites from their own address, 127.0.0.2. For the site that answers nobody, one machine cannot leave a connection attempt unanswered, so the proxy was set to wait three seconds and answer 504, the case RFC 9110 defines. Three more proxies were broken: one hung up, one never answered, and one address had nothing listening. One proxy name, proxy.lab.invalid, belongs to a domain reserved never to exist.

The clients were:

  • the curl in Windows (8.21.0) and the curl of Git for Windows (8.16.0);
  • git 2.51.2;
  • Python 3.13.7 with urllib, and requests 2.32.3 with urllib3 1.26.20;
  • Java 17.0.17 with HttpURLConnection and HttpClient;
  • PowerShell 7.6.6;
  • Chrome 153, headless.

All 13 triage cases and all 51 client cases gave the same result in both runs. The sites and proxies ran on the machine itself.

Sources

Frequently asked questions

What is a proxy server error?
A failure on the way through a proxy. Your machine could not reach the proxy, the proxy would not or could not reach the site, or the site refused the address the proxy gave it. The message usually says which, once you know where to look, and the three commands at the top of this page tell the cases apart.
What does "Received HTTP code 403 from proxy after CONNECT" mean?
The proxy refused to open a tunnel to that site, so the site never saw your request. curl 7.86.0 and older print that line; newer versions print "CONNECT tunnel failed, response 403". A proxy answers 403 when its own rules refuse the destination. The default setup of Squid, for example, opens tunnels to port 443 only. Ask whoever runs the proxy to allow the site, or use another proxy.
What does "Unable to tunnel through proxy. Proxy returns" mean in Java?
It is how HttpURLConnection, in Java, says that the proxy refused the tunnel. The text in quotes is the status line the proxy sent, so "HTTP/1.1 502 Bad Gateway" means the proxy could not reach the site. In our lab, Java 17 threw it for a 403, a 502 and a 504 from the proxy. For a 407 with no login set, it returned the status 407 instead: our 407 guide covers how Java sends a login.
What does "Proxy CONNECT aborted" mean?
The proxy closed the connection without answering the tunnel request. curl prints it with exit code 56, and git prints it at the end of its "unable to access" line. In our lab a proxy that read the request and hung up caused it, and so did an http:// proxy address pointed at a SOCKS port. Check the protocol in the address first.
Why does Chrome show ERR_TUNNEL_CONNECTION_FAILED whatever the proxy says?
Chrome ignores the answer a proxy gives to a tunnel request, on purpose, so that a proxy cannot pose as the site. Any answer except 200 and 407 becomes ERR_TUNNEL_CONNECTION_FAILED. In our lab that held for a 403, a 502 and a 504. Run curl -v with the same proxy to see the real code.
Is 502 Bad Gateway the proxy's fault or the site's?
It depends on when it arrived. In curl -v, a 502 before the line "CONNECT tunnel established" came from your proxy, which could not reach the site. A 502 after the tunnel opened came from the servers of the site. Chrome and Firefox never show the answer a proxy gives to a tunnel request, so a 502 page on an https:// site came from beyond the tunnel: the site, or a device on your network that inspects encrypted traffic.
Why does my scraper get 200 OK and still no data?
Because a check page is a valid page. In our lab, a site that sent the address of the proxy a "verify you are a human" page answered 200 OK, and only a check on the content caught it. Test for text that only the real page carries, not for the status code alone.

Get proxies that are alive right now

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump. When the location has to survive a real check, the paid network holds up.

129M+ proxy checks run · 100+ countries · HTTP / HTTPS / SOCKS · re-checked every few minutes · no signup

HProxy.

Honest guides and comparisons on proxies, scraping and staying unblocked, from the team that runs the network.

RSS feed