407 Proxy Authentication Required
A 407 Proxy Authentication Required status tells you that the proxy, not the website, refused your request because it did not receive valid credentials. The proxy says which login scheme it wants in a Proxy-Authenticate header. The fix is almost always the username, the password, how they are encoded, or a client that never sends them.
In brief
- RFC 9110 defines 407 as the proxy-side version of 401: the client must authenticate to the proxy first.
- Common causes: wrong or regenerated credentials, unencoded special characters, an HTTP scheme on a SOCKS port, a missing allowlist entry, or a client that drops the credentials.
- The same bad password shows up differently by site: an error for https:// sites, a plain 407 response for http:// sites.
- Chrome's --proxy-server switch takes no credentials, so browsers need an automation tool or extension to answer the 407.
- A 407 never comes from the website, so it does not mean the site detected or blocked the proxy.
What 407 means
RFC 9110, the current HTTP semantics standard, defines 407 as similar to 401 Unauthorized, but indicating that the client needs to authenticate itself in order to use a proxy. The proxy must send a Proxy-Authenticate header that says which authentication scheme it will take, and the client answers with a Proxy-Authorization header. MDN's 407 reference summarises the same exchange.
This is the exchange our test proxy produced for a wrong password:
> CONNECT api.ipify.org:443 HTTP/1.1
> Host: api.ipify.org:443
> Proxy-Authorization: Basic bGFiLXVzZXI6d3Jvbmc=
>
< HTTP/1.1 407 Proxy Authentication Required
< Proxy-Authenticate: Basic realm="lab"
< Connection: close
* CONNECT tunnel failed, response 407
The client sent credentials, the proxy rejected them and named Basic as the scheme. Basic authentication, defined in RFC 7617, is the username and password joined by a colon and Base64-encoded. It is encoding, not encryption, which is one more reason to keep the password out of shared logs.
What 407 is not: it is not the website blocking you, not a rate limit and not an IP ban. Those come back as 403, 429 or a challenge page after the proxy has already let you through.
Causes
In the order worth checking:
- Wrong or old credentials. Copied with a trailing space, or from before a password reset or line replacement. A replaced Coronium line comes with new credentials.
- Special characters not encoded. In a proxy URL,
@,:,/,#and%in a password break parsing. Encode them, or use a separate password field. - Protocol and port mismatch. An HTTP client pointed at a SOCKS5 port, or the reverse. Coronium lines have separate HTTP and SOCKS5 ports.
- No credentials sent. The proxy URL in one setting but the client reads another, for example
https_proxyset while the code uses its own proxy option without credentials. - IP allowlist instead of a password. Some proxies authenticate by your source IP. If your server's public address changed, the proxy answers 407. The allowlisting guide explains which IP to add.
- Malformed username parameters. Pool providers put country or session options in the username; a typo makes it an unknown user.
- A middlebox removing the header. Corporate proxies or chained proxies sometimes strip Proxy-Authorization before it reaches the next hop.
Fixes per client
curl. curl -x http://HOST:PORT --proxy-user 'USER:PASSWORD' https://api.ipify.org sends the raw password without encoding. With a wrong password, curl 8.7.1 printed curl: (56) CONNECT tunnel failed, response 407 for an HTTPS site, and for an HTTP site printed the 407 page with exit status 0. Use --fail in scripts. The cURL proxy guide has the full set.
Python Requests. Put credentials in the proxy URL, percent-encoded, as the Requests documentation shows. We ran the same wrong password against both kinds of site with Requests 2.32:
https://api.ipify.org ProxyError: ... Tunnel connection failed: 407 Proxy Authentication Required
http://api.ipify.org status 407
That difference explains a familiar report: "it works for some URLs and fails for others". If your code only checks for exceptions, http:// requests return a 407 silently. Call raise_for_status(). More in the Python Requests proxy guide.
Playwright. Its proxy option takes server, username and password as separate fields; pass the raw password there. See Playwright proxy rotation.
Selenium and Chrome. Chrome's --proxy-server switch has no place for credentials, so a plain Chrome launch answers the 407 with a login prompt or fails. The Selenium authentication guide shows the tested setup.
Node.js. Native fetch and Undici take a proxy agent with credentials; Axios has its own proxy.auth. See Node.js fetch and Axios.
Allowlist vs password
| Symptom | Likely cause | Fix |
|---|---|---|
| 407 on every request, every client | Wrong or old credentials | Copy them again from the dashboard |
| 407 only when the password has symbols | Unencoded characters in the URL | Percent-encode, or use a separate field |
| 407 from one server but not another | IP allowlist, or a different config on that server | Check the source IP and environment variables |
| 407 only in the browser | Chrome launched with credentials in --proxy-server | Use an automation tool or extension |
| HTTP sites return 407, HTTPS sites raise errors | Same bad credentials, different client paths | Fix the credentials; check status codes |
Password authentication travels with the request, so it works from any machine, container or cloud region. An IP allowlist ties access to the public address your requests come from, which is simpler for tools that cannot send credentials but breaks whenever that address changes.
Choose by where the client runs:
- Laptops, rotating cloud workers and serverless functions: a username and password.
- A fixed server with a stable public IP and a tool that cannot send credentials: an allowlist.
Coronium lines use a username and password on both the HTTP and SOCKS5 port, so the commands in this guide work as written. If a 407 persists after you have checked every cause above, test the line itself with curl from a second machine before changing your code: if curl succeeds there, the problem is in the client configuration.
Sources and review scope
Sources reviewed October 30, 2026. Standards, vendor documents and regulator pages were read on the date above. Where a page shows commands, they were run with curl 8.7.1 and Python Requests 2.32 against a local authenticated test proxy; addresses in the output are replaced with documentation ranges. Vendor parameters change, so confirm them in the vendor documentation linked here.
Frequently asked questions
More proxy questions
Short answers first, then the detail, with the standard or vendor document behind each claim.
Related workflows
Dedicated 4G and 5G carrier lines, with live stock and prices for each country and carrier.
What each proxy and HTTP error code means.
Which IP an allowlist needs, and when a password is better.
A step-by-step diagnosis for a line that will not connect.
Every curl proxy option, tested.
URL and colon formats, encoding and conversion.
Where to get a dedicated line
A Coronium mobile proxy is one physical device with its own SIM, rented to one customer. It connects over HTTP or SOCKS5, the IP changes by dashboard button, API link or timer, and data is not metered on dedicated lines. Brazil lines are the exception: 20 GB of data a month and a new IP on request only, with no timer. Stock and prices differ by country and carrier.