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 -sS -x http://HOST:PORT -U "USER:WRONG" https://example.com/
curl: (56) CONNECT tunnel failed, response 407requests.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')))HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="proxy"
Connection: closeWhat 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.
- 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.
- 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. - 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 noProxy-Authorizationheader and answers 407. - 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.
- 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?
Read the proxy's answer with curl
Send one request with verbose output. A
< HTTP/1.1 407line directly after> CONNECTis the proxy refusing.200 Connection establishedmeans the login worked, and any later error comes from the site.Show the proxy's answercurl -v -x http://HOST:PORT -U "USER:PASS" https://example.com/ -o /dev/null 2>&1 \ | grep -iE "^(> CONNECT|< HTTP|< x-proxy-reason|\* CONNECT)"Rule out encoding
-Uneeds 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 passwordread -rs PROXY_PASS printf %s "$PROXY_PASS" | python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.stdin.read(), safe=""))'Check the address the proxy sees
For IP whitelist authentication, compare the list with the addresses these commands print.
Your public IPv4 and IPv6 addressescurl -4 -s https://api.ipify.org; echo curl -6 -s https://api64.ipify.org; echoCheck 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_REQUIREDwhen 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 thehttp://scheme for the proxy even when the site is HTTPS, unless your provider documents TLS to the proxy on that port.Python requestsfrom 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 refusedCONNECTarrives as a response with status 407, not as an error.Node.js with https-proxy-agentimport 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-serverand 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:
| X-Proxy-Reason | What 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.
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.
Related errors
ERR_TUNNEL_CONNECTION_FAILED
The proxy answered the browser's CONNECT with an error. The status it sent is the real cause.
curl error 56
Recv failure, Proxy CONNECT aborted or CONNECT tunnel failed: what each curl (56) message means.
403 Forbidden through a proxy
Usually the website's refusal after the tunnel opened; sometimes the proxy refusing the destination.
The proxy checker error codes page maps each checker code to the stage that failed, and proxy errors explained covers timeouts and slow connections.