Skip to content

407 Proxy Authentication Required: causes and fixes

A 407 is the proxy's own answer: it wants credentials it did not get or did not accept, so the request never reached the website. The usual causes are a mistyped username or password, a password with special characters that was not percent-encoded in the proxy URL, and a client that never sends credentials at all. Run the request once with curl -v to see the proxy's answer and any reason it gives.

Reviewed by John Hale. Last updated .

What it looks like

curl
$ curl -sS -x http://HOST:PORT -U "USER:WRONG" https://example.com/
curl: (56) CONNECT tunnel failed, response 407

Python requests
requests.exceptions.ProxyError: HTTPSConnectionPool(host='example.com', port=443): Max retries exceeded with url: / (Caused by ProxyError('Unable to connect to proxy', OSError('Tunnel connection failed: 407 Proxy Authentication Required')))

The proxy's response
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="proxy"
Connection: close

What does 407 Proxy Authentication Required mean?

RFC 9110 defines 407 as the proxy's version of 401: authenticate with the proxy before it forwards anything. The proxy names the scheme it accepts in Proxy-Authenticate, almost always Basic, and the client answers with Proxy-Authorization.

For an HTTPS site, the 407 is the answer to your client's CONNECT request, so no TLS handshake with the site has started. The website cannot be the cause, and changing headers, cookies or the user agent does nothing for a 407.

A browser answers a 407 by asking for the proxy's username and password. A library usually stops and reports the status, without the response body where a proxy may have explained the refusal.

What causes a 407?

Most likely first.

  1. The username or password is wrong. A typo, a space or line break copied along with the credentials, or an old password after it was changed. Many providers also put options such as country or session in the username, so a misspelled option can look like a wrong username.
  2. Special characters in the password were not encoded. Inside a proxy URL such as http://USER:PASS@HOST:PORT, the characters @, :, /, # and % have meaning, so a password containing @ is split in the wrong place. Percent-encode it (@ becomes %40) or pass the credentials in a separate option.
  3. The client never sends the credentials. Chrome ignores a username and password written into --proxy-server, and Selenium's proxy setting has no place for them. The proxy then sees a request with no Proxy-Authorization header and answers 407.
  4. Your address is not on the IP whitelist. With IP whitelist authentication, the proxy admits only the public addresses you listed. If yours changed, or your connection leaves over IPv6 while the list holds your IPv4 address, the proxy asks for credentials instead.
  5. The account cannot carry traffic. Some providers, TrueProxies included, answer 407 when a plan has expired, used its traffic or reached a limit, because the check happens at the same step as the password.

How do you find the cause of a 407?

  1. Read the proxy's answer with curl

    Send one request with verbose output. A < HTTP/1.1 407 line directly after > CONNECT is the proxy refusing. 200 Connection established means the login worked, and any later error comes from the site.

    Show the proxy's answer
    curl -v -x http://HOST:PORT -U "USER:PASS" https://example.com/ -o /dev/null 2>&1 \
      | grep -iE "^(> CONNECT|< HTTP|< x-proxy-reason|\* CONNECT)"

  2. Rule out encoding

    -U needs no encoding. If -U "USER:PASS" works and the same credentials fail inside -x http://USER:PASS@HOST:PORT, the password needs percent-encoding. This prints the encoded form without putting the password in your shell history:

    Percent-encode a password
    read -rs PROXY_PASS
    printf %s "$PROXY_PASS" | python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.stdin.read(), safe=""))'

  3. Check the address the proxy sees

    For IP whitelist authentication, compare the list with the addresses these commands print.

    Your public IPv4 and IPv6 addresses
    curl -4 -s https://api.ipify.org; echo
    curl -6 -s https://api64.ipify.org; echo

  4. Check the account, then test from outside your network

    Look at the provider's dashboard for an expired plan or used-up traffic. Then paste the proxy into the proxy checker, which reports AUTH_REQUIRED when the proxy asks for or rejects authentication.

How do you fix a 407?

  • Copy the credentials again

    Copy them from the provider's dashboard, trim spaces and line breaks, and stop every client that still sends an old password.

  • Encode the password, or keep it out of the URL

    In Python, build the proxy URL with urllib.parse.quote. Use the http:// scheme for the proxy even when the site is HTTPS, unless your provider documents TLS to the proxy on that port.

    Python requests
    from urllib.parse import quote
    import requests
    
    proxy = f"http://{quote(USER, safe='')}:{quote(PASS, safe='')}@HOST:PORT"
    r = requests.get("https://example.com/", proxies={"http": proxy, "https": proxy}, timeout=30)
    print(r.status_code)

  • Read the status in Node.js

    With https-proxy-agent, a refused CONNECT arrives as a response with status 407, not as an error.

    Node.js with https-proxy-agent
    import https from "node:https";
    import { HttpsProxyAgent } from "https-proxy-agent";
    
    const user = encodeURIComponent(process.env.PROXY_USER);
    const pass = encodeURIComponent(process.env.PROXY_PASS);
    const agent = new HttpsProxyAgent(`http://${user}:${pass}@HOST:PORT`);
    
    https.get("https://example.com/", { agent }, (res) => {
      console.log(res.statusCode); // 407 here is the proxy's answer
      res.resume();
    });

  • Give browsers credentials the way they accept them

    For Chrome started with --proxy-server and for Selenium, use IP whitelist authentication, or the proxy login options in Playwright and Puppeteer.

If you use TrueProxies

The gateway answers 407 with one sentence that names the check that failed, in the X-Proxy-Reason header and the response body, then closes the connection. A refusal uses no traffic. The sentences you are most likely to see:

TrueProxies 407 reasons and what to do
X-Proxy-ReasonWhat to do
Wrong proxy password. Check the credentials on your service page.Copy the proxy password again from the Proxy setup tab. After Change password, the old password keeps working for 2 minutes.
Username not recognised. Check the username on your service page.Copy the username again. Options go after it with hyphens, as in USER-country-de.
Username not recognised, or the service it belongs to has ended. Check your service page.Check that the service is under Current in the dashboard.
No credentials sent, and this address is not on the service's trusted IP list.Send the username and proxy password, or add the address to the IP whitelist.
The targeting options in your username are not valid for this service. Check spelling, and do not repeat an option.Use two-letter country codes (country-us, not country-usa) and each option once.
This service has used its traffic allowance. Add traffic to continue.Add a traffic pack with Top-up.
Too many wrong usernames or passwords from this address in the last minute. Correct logins still connect; check the username and proxy password on every client at this address.Stop the clients that still send an old login. The lockout ends a minute after the wrong logins stop.

SOCKS5 has no field for a reason, so a refused SOCKS5 login just fails: send the same login once to the HTTP port, 8080, with curl -v to read the sentence. The errors reference lists every reason.

Test the proxy from outside your network

The free proxy checker connects from our servers and reports the failed stage as a code, so you can tell a proxy problem from one on your computer or network.

Run the proxy checker

Questions about 407 Proxy Authentication Required

Why does Python say Tunnel connection failed: 407 Proxy Authentication Required?

The proxy refused the CONNECT for an HTTPS URL, and requests does not show the proxy's response body. Run the same proxy with curl -v to read any reason, and check that special characters in the password are percent-encoded.

Can a 407 come from a proxy I did not configure?

Yes. A corporate proxy, an antivirus web shield or a system proxy left behind by an app can sit between you and your provider and ask for its own credentials. Check the system proxy settings and the HTTP_PROXY and HTTPS_PROXY environment variables.

Is 407 the same as 401?

Same idea, different party. 401 means the website wants you to sign in; 407 means the proxy does. A 401 arrives through an open tunnel, a 407 instead of one.