Quick answer
What does ERR_TUNNEL_CONNECTION_FAILED mean with a proxy?
net::ERR_TUNNEL_CONNECTION_FAILED means Chrome asked the proxy to open a tunnel to an HTTPS site and the proxy did not answer 200 Connection established. The browser hides the real status. With CrawlRelay residential proxies, the cause is usually missing credentials in Playwright or Puppeteer, then a target the gateway cannot reach. Reproduce with curl -v to see the real code.
ERR_TUNNEL_CONNECTION_FAILED at a glance
| Error | ERR_TUNNEL_CONNECTION_FAILED |
|---|---|
| Type | Chromium network error |
| Sent by | Your browser, after the proxy refused or failed the CONNECT request |
| Defined in | CONNECT method: RFC 9110, section 9.3.6 |
| Retry it? | Only after you find the status behind it |
| First check | Reproduce with curl -v to see the real status of the CONNECT |
What does ERR_TUNNEL_CONNECTION_FAILED mean?
To load an HTTPS page through an HTTP proxy, the browser first sends CONNECT host:443. If the proxy answers 200, the browser starts TLS inside the tunnel. Any other answer, such as 407, 403 or 502, ends the attempt, and Chromium reports one generic error.
That is why this error tells you where the failure happened, the tunnel, but not why. The why is the status code the proxy sent, which you can see with curl.
What does ERR_TUNNEL_CONNECTION_FAILED look like in Python, curl, Node.js and browsers?
The same failure prints differently in every tool. These are the messages to search your logs for:
- Playwright:
page.goto: net::ERR_TUNNEL_CONNECTION_FAILED at https://... - Puppeteer:
Error: net::ERR_TUNNEL_CONNECTION_FAILED at https://... - Chrome address bar: 'This site can't be reached' with the code
ERR_TUNNEL_CONNECTION_FAILED - Selenium with Chrome: the same code inside a
WebDriverException
What causes ERR_TUNNEL_CONNECTION_FAILED?
Most likely first:
- No credentials sent (hidden 407). Chrome ignores a username and password inside
--proxy-server. - A refused destination (hidden 403), such as a category blocked by the proxy's usage policy.
- An unreachable target (hidden 502 or 504): a dead host, a typo or a DNS failure at the exit.
- A wrong port: pointing the browser at the SOCKS5 port as if it were HTTP, or the reverse.
How do I diagnose ERR_TUNNEL_CONNECTION_FAILED step by step?
- Run the same URL through curl with
-v(command below) and read the line afterCONNECT. - A
407means credentials; a403means a refused destination; a502or504means the target or the exit. - Confirm the browser uses the HTTP port for an
http://proxy server. - Test a simple page such as
https://api.ipify.orgbefore your real target.
# Use the URL that fails; with https://api.ipify.org instead, you test the gateway alone.
# "HTTP/1.1 200 Connection established" first, then the site's own status: the site answered.
curl -v -x http://USERNAME:[email protected]:7777 https://TARGET_URL
# Same test through the SOCKS5 port, with DNS resolved at the exit
curl -v --socks5-hostname gw.crawlrelay.com:7778 --proxy-user USERNAME:PASSWORD https://TARGET_URLHow do I fix ERR_TUNNEL_CONNECTION_FAILED?
- Playwright: pass
server,usernameandpasswordin theproxyoption, per browser or per context. See the Playwright guide. - Puppeteer: launch with
--proxy-server=http://host:portand callpage.authenticate()before the firstgoto. See the Puppeteer guide. - Selenium: run a small local forwarder that adds the credentials. See the Selenium guide.
- Check the destination against our Acceptable Use Policy.
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(proxy={
"server": "http://gw.crawlrelay.com:7777",
"username": "USERNAME-country-us",
"password": "PASSWORD",
})
page = browser.new_page()
response = page.goto("https://api.ipify.org")
print(response.status, page.inner_text("body"))
browser.close()Should I retry after ERR_TUNNEL_CONNECTION_FAILED?
Retry only once you know the hidden status. A hidden 407 or 403 will repeat forever; fix the configuration. A hidden 502 or 504 can be retried on a new exit, like any gateway error.
How does ERR_TUNNEL_CONNECTION_FAILED apply to CrawlRelay?
CrawlRelay's HTTP port carries HTTPS through CONNECT tunnels, which every Chromium-based tool supports. Use the HTTP port for browsers: Chromium does not support SOCKS5 with a username and password.
Gateway: gw.crawlrelay.com, port 7777 (HTTP, HTTPS through CONNECT) and port 7778 (SOCKS5). Username format: USERNAME-country-{cc}-state-{state}-city-{city}-zip-{zip}-asn-{asn}-session-{id}-ttl-{minutes}. Related: 407 Proxy Authentication Required · ERR_PROXY_CONNECTION_FAILED · Playwright guide.
ERR_TUNNEL_CONNECTION_FAILED: questions developers ask
Why does curl work but Playwright shows ERR_TUNNEL_CONNECTION_FAILED?
Because curl sends the credentials from the proxy URL, while Chromium ignores credentials written into the proxy server address. In Playwright, pass username and password as separate fields of the proxy option. In Puppeteer, call page.authenticate() before navigating.
Can I use SOCKS5 proxies with authentication in Chrome?
Not directly. Chromium supports SOCKS5 proxies but not SOCKS5 username and password authentication. Use the gateway's HTTP port instead, which handles HTTPS sites through CONNECT tunnels, or run a local forwarder that authenticates for the browser.
Is ERR_TUNNEL_CONNECTION_FAILED caused by the website?
Rarely directly. The tunnel is between the browser and the proxy, so the error happens before the website sees a TLS handshake. The website can be the indirect cause when it is unreachable and the proxy answers 502 or 504 to the CONNECT request.
Other proxy errors in this reference
HTTP status codes
- 401 Unauthorized vs 407
- 403 Forbidden
- 407 Proxy Authentication Required
- 429 Too Many Requests
- 502 Bad Gateway
- 503 Service Unavailable
- 504 Gateway Timeout
Browser and client errors
Connection and TLS errors
Residential proxies with docs that cover the failure cases
CrawlRelay residential proxies from $0.50/GB, traffic that never expires.