# ERR_PROXY_CONNECTION_FAILED in Chrome: the first hop

> Chrome's proxy connection failed error means it never reached the proxy address it was given. Check the host, the port and anything local before the exit.

Source: https://mosaicbrowser.com/blog/err-proxy-connection-failed

## ERR_PROXY_CONNECTION_FAILED is about the first hop

Chrome's proxy connection failed error means it never reached the proxy address it was given. Check the host, the port and anything local before the exit.

![-130: Chrome never reached the proxy at all, beside a screenshot: routing Mosaic launches through Proxyman, Charles or mitmproxy to read their traffic](https://mosaicbrowser.com/covers/err-proxy-connection-failed.webp)

ERR_PROXY_CONNECTION_FAILED in Chrome is a complaint about the first hop. The browser was handed a proxy, tried to open a socket to it, and got nothing back: the proxy's name wouldn't resolve, or the port refused or timed out. The site you asked for was never contacted, and neither was whatever exit sits behind the gateway. Look at the host and port you typed, and at any program on your own Mac or PC that was meant to be listening there and isn't.

## What ERR_PROXY_CONNECTION_FAILED means in Chromium's source

It is entry -130 in Chromium's `net/base/net_error_list.h`, and the comment above it is unusually exact. It says Chrome "could not create a connection to the proxy server", that the error happened "either in resolving its name, or in connecting a socket to it", and then: "Note that this does NOT include failures during the actual "CONNECT" method of an HTTP proxy."

That last sentence is the useful one. Chrome keeps the stages of a proxied request apart and gives each its own code:

| Stage | Error when it fails |
| --- | --- |
| Resolve the proxy's name and open a TCP socket to it | `ERR_PROXY_CONNECTION_FAILED` (-130) |
| Ask an HTTP proxy to `CONNECT` to the site, get anything but 200 | `ERR_TUNNEL_CONNECTION_FAILED` (-111) |
| Complete the SOCKS handshake to the target | `ERR_SOCKS_CONNECTION_FAILED` (-120) |

There's a catch in the SOCKS row. Open `socks_connect_job.cc` and you'll see that when the TCP connect to the SOCKS server fails, the job hands back -130. You only get -120 after a SOCKS server has picked up and then botched the handshake. So typing 1080 where the seller meant 1085 gives you the same -130 as a dead HTTP gateway would: nobody was home at that address either way.

So -130 tells you something definite: no proxy software ever spoke to the browser. A proxy that is up but refusing you, or one asking for a password, gives a different code.

Mosaic is a desktop app

Email yourself the link and open it on your computer.

[How it works: Provider minting](https://mosaicbrowser.com/features/proxy-providers)

## Why one dead proxy breaks every site at once

Chromium treats -130 as grounds to try the next proxy in its list. The fallback table in `proxy_fallback.cc` names it first, alongside refused, reset and timed-out connections. When a PAC script or a policy hands Chrome several proxies, a dead first one costs a delay and the next one carries the page.

With one proxy set by hand there is no next one, so every request fails the same way, on every site. That is why this error tends to arrive as "nothing loads" rather than "one site is down". Chrome also remembers a proxy that failed and avoids it for a while; `chrome://net-internals/#proxy` has a Clear bad proxies button for after you fix it.

## The usual causes, in the order we would check them

1. **Wrong address.** Usually a typo, or a port copied from the seller's other product, or a gateway IP they retired last month. Sellers like to run HTTP on one port and SOCKS5 on the next one up on the same host, and [the port number names the protocol](https://mosaicbrowser.com/blog/port-number-names-protocol) is the test we ran to find out which was which.
2. **The name won't resolve.** Give Chrome `gate.example` and let your resolver fail on it, and you get -130 rather than ERR_NAME_NOT_RESOLVED. The name that failed belonged to the proxy, so Chromium files it there.
3. **A local listener went away.** VPN clients, antivirus "web shields" and Charles-style debuggers like to set the system proxy to `127.0.0.1:8888` or similar. When one of them quits or crashes it often leaves that setting in place, and now every request goes to a port with nobody on it.
4. **A firewall eats it.** Office networks that let out 80 and 443 and block the rest will make a gateway on 8000 or 10000 hang until it times out.

Run the same address through curl to tell these apart without the browser:

```
curl -v -x http://gate.example:8000 https://example.com/ -o /dev/null

```

curl says "Could not resolve proxy" for cause two and "Connection refused" for one or three. If it sits there for a minute and then gives up, think firewall. And if it gets far enough to print a `CONNECT` reply, the first hop is fine and Chrome ought to be showing -111; [ERR_TUNNEL_CONNECTION_FAILED](https://mosaicbrowser.com/blog/err-tunnel-connection-failed) is about what the proxy said back.

## The first hop in Mosaic is on your own computer

In Mosaic, a profile with a proxy does not usually point its browser at the seller's gateway. By default it points at a relay on `127.0.0.1`, on a port the operating system picks when the profile starts, one relay per profile. The relay is there because Chromium's `--proxy-server` switch cannot carry a username and password, and because only a local first hop lets the engine refuse to resolve any host name itself, so DNS goes through the proxy too.

This shifts which error you see. Chrome can always reach the relay, since it sits on loopback and was started for that one browser. When the seller's gateway behind it is wrong or down, `relay.ts` writes `HTTP/1.1 502 Bad Gateway` back on the browser's `CONNECT`, and Chrome turns that into ERR_TUNNEL_CONNECTION_FAILED, not -130. In practice you rarely get that far: the launcher won't open a window until the proxy has answered and tunnelled, and if it hasn't, the refusal names the proxy and what went wrong.

So on the default settings, -130 inside a Mosaic profile means the browser could not reach a local address. One case is easy to make on purpose. With traffic inspection on (Settings › Network routes launches through Proxyman, Charles, mitmproxy, Fiddler or Burp), the browser's first hop is the inspector. Quit the inspector while a profile is open and that profile's browser is now pointed at a closed port, which is cause three from the list above. Start the inspector again, or stop the profile and launch it after turning inspection off, because a proxy setting reaches the next launch, not a browser that is already open. With the profile's "Resolve DNS through the proxy only" switch left on, as it is by default, any other -130 in a profile we would treat as our bug rather than yours. Turn that setting off for a proxy with no username and the browser goes straight to the gateway again, and the four causes above apply as written. How a seller's gateway line becomes one proxy per profile is on [proxy providers](https://mosaicbrowser.com/features/proxy-providers).

## Questions

### What does ERR_PROXY_CONNECTION_FAILED mean in Chrome?

Chrome is set to use a proxy and could not open a connection to it: the proxy's host name did not resolve, or the socket to its address and port was refused or timed out. It is net error -130 in Chromium's list.

### Is ERR_PROXY_CONNECTION_FAILED the same as ERR_TUNNEL_CONNECTION_FAILED?

No. -130 means the proxy was never reached. -111, the tunnel error, means the proxy was reached and answered the CONNECT request with something other than 200.

### Why do I get ERR_PROXY_CONNECTION_FAILED when I never set a proxy?

Something else set one for you. VPN clients, antivirus suites, debugging proxies and managed work policies all like to point the system proxy at 127.0.0.1. If that program has quit, the port is empty and every page fails with -130 until the setting is cleared.

### How do I test the proxy outside Chrome?

Point curl -v -x at the same host and port. "Could not resolve proxy" or "Connection refused" from curl means the address is the problem, and Chrome was right.

## Related

[What ERR_TUNNEL_CONNECTION_FAILED is telling you](https://mosaicbrowser.com/blog/err-tunnel-connection-failed): Chrome's tunnel connection failed error means the proxy refused the CONNECT tunnel. In our runs the usual cause was a sticky session the gateway had retired.

[The port number told us whether a proxy was SOCKS5](https://mosaicbrowser.com/blog/port-number-names-protocol): Nothing in host:port:user:pass says HTTP or SOCKS5, and curl assumes HTTP. At CatProxies we asked the port: 11000 answered SOCKS5, 10000 HTTP.

[A session token on a rotating port is a 400, not a no-op](https://mosaicbrowser.com/blog/session-token-on-rotating-port): "Can not use -session- on rotating ports" means the port, not the username, decides stickiness. We had written the opposite, until we asked the gateway.

[Provider accounts: one gateway line, one exit per profile](https://mosaicbrowser.com/features/proxy-providers): Paste your proxy seller's gateway line once and Mosaic mints a separate session for every profile, so each one browses from its own exit address.

[A CONNECT to a raw IP means your machine resolved the name](https://mosaicbrowser.com/blog/a-numeric-connect-means-dns-leaked): To check if DNS goes through your proxy, read what the proxy is asked for. CONNECT example.com:443 means it resolved the name; a raw IP means you did.

[DNS prefetching, the lookup that skips your proxy](https://mosaicbrowser.com/blog/dns-prefetch-and-proxies): Chrome's DNS prefetcher resolves names through your own resolver even with a proxy set. Mapping every name to NOTFOUND makes the leak fail closed.

[A proxy that answers HTTP and refuses CONNECT](https://mosaicbrowser.com/blog/proxy-http-works-https-fails): A proxy that works for HTTP but not HTTPS is refusing CONNECT, the tunnel every HTTPS page needs. A check that fetches a plain-HTTP page cannot see it.

[socks5 and socks5h: where Chrome resolves the name](https://mosaicbrowser.com/blog/socks5-and-socks5h-in-chrome): In curl, socks5h sends the hostname to the proxy and socks5 resolves it locally. Chrome's socks5 already sends the name; the leak is elsewhere.

## Mosaic, on your own computer

The browser this blog is about: its own Chromium, fingerprints from real machines and a proxy exit per profile. Free holds 3 profiles. Pro is $49 a month for any number.

Mosaic is a desktop app

Email yourself the link and open it on your computer.
