Geonode logo
Proxy and connection errors

How to Fix ERR_TUNNEL_CONNECTION_FAILED

Read the proxy's status code in Chrome or curl, then apply the matching fix, most common first.

Updated

TL;DR

ERR_TUNNEL_CONNECTION_FAILED means Chrome reached your proxy and asked it for a tunnel to an HTTPS site, and the proxy refused. Chrome only reports the refusal; the fastest fix is to check the site's hostname and port, then the username and password the proxy expects.

What the error looks like in each client

Chrome drops the proxy's reply and shows only the code. curl, Python and Java print the proxy's status, and git repeats curl's text.

WhereWhat you see
ChromeThis site can't be reached. The webpage at https://example.com/ might be temporarily down or it may have moved permanently to a new web address. ERR_TUNNEL_CONNECTION_FAILED
Puppeteer page.goto()net::ERR_TUNNEL_CONNECTION_FAILED at https://example.com
curl (most installed versions; the newest show (7))curl: (56) CONNECT tunnel failed, response 403
curl (older versions, such as Ubuntu 22.04)curl: (56) Received HTTP code 400 from proxy after CONNECT
Python requestsProxyError('Unable to connect to proxy', OSError('Tunnel connection failed: 403 Forbidden'))
Java HttpURLConnectionjava.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 500 Internal Server Error"
Firefox (proxy answers 403 or 429)The proxy server is refusing connections

Why this happens

Your proxy refused to open a secure connection to the site for you.

For an https:// page, Chrome sends the proxy a CONNECT request naming the site's host and port, and needs a clean 200 back. A 403 from the proxy's rules or a 503 for an unreachable site ends in this error.

Diagnose your tunnel error first

The first two checks need only Chrome; the last two read the proxy's reply with curl.

  • Open another HTTPS site through the same proxy; if it loads, the proxy refuses or cannot reach only the site that failed.

  • In chrome://net-export, click Start Logging to Disk, reload, then Stop Logging; at netlog-viewer.appspot.com, the event HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS starts with the proxy's status line.

  • Run curl -x http://USERNAME:PASSWORD@HOST:PORT -w "%{http_connect}" https://example.com (curl.exe in Windows PowerShell); the number printed last is the proxy's reply to CONNECT.

  • If that number is 407, the proxy wants a login; 403 usually means its rules refused the site, the port or your IP.

Solutions ranked by effectiveness

Work down the cards and stop once the site opens; the third is for scripts and command-line tools.

  1. Most common fix

    Check the site's hostname and port

    Applies when the proxy's code is 400, 403, 404 or 5xx and only this site fails. Correct the address you ask the proxy to reach.

    1. Fix hostname typos; the proxy looks names up, so changing DNS servers won't help.

    2. Use port 443 if the site offers it; Squid's defaults refuse CONNECT to other ports.

    3. On a work or school proxy, ask the admin to allow the site or port.

  2. Check next

    Send the proxy its username and password

    Applies when curl, Python or Java reports 407 after CONNECT. The proxy got no valid login, so it opened no tunnel.

    1. Copy the proxy username and password from your provider's dashboard again.

    2. Put them in the proxy URL: http://USERNAME:PASSWORD@HOST:PORT.

    3. Rerun the curl check; 200 means the proxy opened the tunnel.

  3. For developers

    Keep local and internal hosts off the proxy

    Applies when curl or a script fails after CONNECT only for localhost or internal hosts. Unlike Chrome, these clients send even localhost to the proxy, so list such hosts in NO_PROXY.

    export HTTPS_PROXY="http://USERNAME:PASSWORD@proxy.geonode.io:9000"
    export NO_PROXY="localhost,127.0.0.1,.corp.example"
    
    curl -sS -o /dev/null -w "%{http_code}\n" https://example.com
    curl -sS -o /dev/null -w "%{http_code}\n" https://git.corp.example

Stop the tunnel error from coming back

Four habits that stop a working proxy setup from failing again with this error.

  1. Set proxies per job, not in a shared shell profile that every tool started there inherits.

  2. Do not count on a PAC file's backup proxy; Chrome falls back only when a proxy is unreachable.

  3. Log the proxy's status code with each failed request, so a job's log shows why the tunnel failed.

  4. On your own Squid, add each new client network to an allow rule before you connect from it.

Proxy status codes, documentedGeonode's docs say what each proxy status code means and what to do next.
Try residential proxies

Related errors

Learn more

FAQ

It is Chromium's network error -111: Chrome or Edge reached the proxy, which then refused the HTTPS tunnel. ERR_PROXY_CONNECTION_FAILED differs: there the proxy cannot be reached at all.

Older curl releases print it when the proxy answers CONNECT with 400 Bad Request. RFC 9110 makes 400 the usual reply to a CONNECT with an empty or invalid port, so check the port you tunnel to.

The proxy sent it, since a site's own 404 would travel inside the open tunnel. Firefox's network code reads a proxy's 404 as a failed name lookup, so check the hostname.

The proxy hit an unexpected error before the tunnel opened; some proxies send 500 when a DNS lookup times out. Geonode's docs list 500 as an internal error to retry.

The proxy got no answer from the site in time, which is how RFC 9110 defines 504. Current Squid releases send 503 instead when the name lookup or the connection fails.

Java's HttpURLConnection throws it when CONNECT gets any reply but 200, then quotes the proxy's status line. If it shows 407 with a correct login, start Java with -Djdk.http.auth.tunneling.disabledSchemes=""; the JDK blocks Basic logins on tunnels by default.

No password on a whitelisted IP

Scripts on a whitelisted IP open tunnels without sending a proxy password.