# 407 Proxy Authentication Required: what it means and how to fix it

> HTTP 407 Proxy Authentication Required means the proxy rejected or never got your credentials. Exact error messages in Python, curl, Node, and fixes.

- URL: https://crawlrelay.com/docs/errors/407-proxy-authentication-required/
- Last updated: 2026-10-13
- Publisher: CrawlRelay (https://crawlrelay.com)

HTTP status code (4xx, client error): the exact message in each tool, the likely causes in order, and the fix that works.

**Quick answer — What does 407 Proxy Authentication Required mean with a proxy?**

**407 Proxy Authentication Required** means the proxy refused your request because it received no credentials or wrong ones. The target website was never contacted. With CrawlRelay residential proxies, check three things: the username is the one shown in your dashboard, the password matches, and any special character in either is URL-encoded. Retrying the same request never fixes a 407.

## 407 Proxy Authentication Required at a glance

| Attribute | Value |
| --- | --- |
| Error | 407 Proxy Authentication Required |
| Type | HTTP status code (4xx, client error) |
| Sent by | The proxy gateway, never the target website |
| Defined in | RFC 9110, section 15.5.8 (headers: Proxy-Authenticate 11.7.1, Proxy-Authorization 11.7.2) |
| Retry it? | No. The same credentials fail again; fix them first |
| First check | Run the curl test below with the bare username and no targeting parameters |

## What does 407 Proxy Authentication Required mean?

A 407 comes from the proxy, not from the site you want to reach. RFC 9110 describes it as the proxy's version of 401: the client must authenticate with the proxy before anything else happens. The proxy sends a `Proxy-Authenticate` header that names the scheme it accepts, almost always `Basic`. Your client answers with a `Proxy-Authorization` header that carries `username:password` encoded in Base64.

For an HTTPS target, the 407 arrives in reply to the `CONNECT` request that opens the tunnel. That is why many libraries report it as a tunnel or connection error and not as an HTTP status: the TLS session with the website was never started.

## What does a 407 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:

- **Python requests:** `ProxyError('Unable to connect to proxy', OSError('Tunnel connection failed: 407 Proxy Authentication Required'))`
- **curl:** `curl: (56) CONNECT tunnel failed, response 407`
- **Scrapy:** `TunnelError: Could not open CONNECT tunnel with proxy ... [{'status': 407, 'reason': b'Proxy Authentication Required'}]`
- **Chrome, Playwright, Puppeteer:** `net::ERR_TUNNEL_CONNECTION_FAILED`, or a login pop-up in a visible browser
- **Node.js clients on an http:// target:** `Request failed with status code 407`

## What causes a 407?

Most likely first:

- **Wrong username or password.** A typo, an old password after a reset, or the credentials of another sub-user.
- **Unencoded special characters.** A password containing `@`, `:`, `/` or `#` breaks the `user:pass@host` URL. Percent-encode it: `@` becomes `%40`, `:` becomes `%3A`.
- **A broken targeting suffix.** Gateways that read targeting from the username see one long username. A typo in a key or a country code turns it into a username the proxy does not know.
- **Credentials that never leave your code.** Chrome ignores a username and password written inside `--proxy-server`. Puppeteer needs `page.authenticate()`, and Selenium needs a local forwarder.
- **An empty balance.** Check that your account still has traffic left before you debug the code.

## How do I diagnose a 407 step by step?

1. Test the credentials with curl and no targeting at all (command below). A `HTTP/1.1 407` line in the verbose output confirms a credentials problem.
2. Add your targeting parameters back one at a time, re-running the test after each one.
3. Log the proxy URL your program actually builds, with the password masked, and compare it character by character with the dashboard.
4. If curl succeeds and your program fails, the library is not sending the credentials. Read the fix for your tool below.

*Test the failing URL with curl (HTTP port, verbose)*

```bash
# 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:PASSWORD@gw.crawlrelay.com: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_URL
```

## How do I fix a 407?

- **Encode credentials** with `urllib.parse.quote(value, safe='')` in Python or `encodeURIComponent()` in JavaScript before you build the URL.
- **Browsers:** pass `username` and `password` in Playwright's `proxy` option, call `page.authenticate()` in Puppeteer, and use a local forwarder for Selenium. See the [Playwright](https://crawlrelay.com/docs/playwright/) and [Puppeteer](https://crawlrelay.com/docs/puppeteer/) guides.
- **Environment variables:** if you set `HTTPS_PROXY`, quote the whole value in your shell so `@` and `$` survive.
- **Rotate the password** in the dashboard if you suspect a leak, then update every scraper that uses it.

*Python: build the proxy URL with encoded credentials*

```python
from urllib.parse import quote

import requests

user = "USERNAME-country-us"
password = "p@ss:word/1"  # example containing special characters

# safe="" also encodes "/", "@" and ":" inside the credentials
proxy = "http://{}:{}@gw.crawlrelay.com:7777".format(
    quote(user, safe=""), quote(password, safe="")
)
proxies = {"http": proxy, "https": proxy}  # http:// for both keys

r = requests.get("https://api.ipify.org", proxies=proxies, timeout=(10, 30))
print(r.status_code, r.text)
```

*Playwright (Python): credentials as separate fields*

```python
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 a 407?

Do not retry a 407 automatically. A retry with the same credentials returns the same answer, and a tight retry loop only fills your logs. Treat 407 as a configuration error: stop the job, fix the credentials, and restart. If 407 appears suddenly in a job that worked for days, the password was probably changed or the sub-user was disabled.

## How does 407 Proxy Authentication Required apply to CrawlRelay?

The CrawlRelay gateway reads the username and password on each new connection. Targeting and session settings live in the username, so a valid password can still fail when the suffix is malformed. Build the username in one helper function and log its output once at start-up. The [quick-start page](https://crawlrelay.com/docs/) shows the exact format.

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: [401 vs 407](https://crawlrelay.com/docs/errors/401-unauthorized/) · [ERR_TUNNEL_CONNECTION_FAILED](https://crawlrelay.com/docs/errors/err-tunnel-connection-failed/) · [Cannot connect to proxy](https://crawlrelay.com/docs/errors/cannot-connect-to-proxy/).

## 407 Proxy Authentication Required: questions developers ask

### Is a 407 sent by the website I am scraping?

No. A 407 is always sent by a proxy that sits between you and the website. The request never reached the website, so it cannot see your traffic, count it or block you for it. If the website wanted a login, it would answer 401 instead. Fix the proxy credentials and the 407 disappears.

### Why does my code get 407 when curl works with the same proxy?

Your library is not sending the credentials, or it sends them in a different form. The usual causes are credentials typed into a browser flag that ignores them, an environment variable that lost its special characters, or a password that was not URL-encoded. Print the proxy URL your code builds, with the password masked, and compare it with the curl command.

### Does a 407 use traffic from my plan?

A 407 response is a few hundred bytes, and the request never reaches the target, so no page is downloaded. The cost lies elsewhere: a scraper stuck in a 407 retry loop wastes time and fills your logs. Make 407 a hard stop in your error handling.

## Other proxy errors in this reference

- [401 Unauthorized vs 407](https://crawlrelay.com/docs/errors/401-unauthorized/)
- [403 Forbidden](https://crawlrelay.com/docs/errors/403-forbidden/)
- [407 Proxy Authentication Required](https://crawlrelay.com/docs/errors/407-proxy-authentication-required/)
- [429 Too Many Requests](https://crawlrelay.com/docs/errors/429-too-many-requests/)
- [502 Bad Gateway](https://crawlrelay.com/docs/errors/502-bad-gateway/)
- [503 Service Unavailable](https://crawlrelay.com/docs/errors/503-service-unavailable/)
- [504 Gateway Timeout](https://crawlrelay.com/docs/errors/504-gateway-timeout/)
- [Cannot connect to proxy (ProxyError)](https://crawlrelay.com/docs/errors/cannot-connect-to-proxy/)
- [Connection reset by peer (ECONNRESET)](https://crawlrelay.com/docs/errors/connection-reset/)
- [ERR_PROXY_CONNECTION_FAILED](https://crawlrelay.com/docs/errors/err-proxy-connection-failed/)
- [ERR_TUNNEL_CONNECTION_FAILED](https://crawlrelay.com/docs/errors/err-tunnel-connection-failed/)
- [Read timed out (ReadTimeout)](https://crawlrelay.com/docs/errors/read-timeout/)
- [SOCKS5 proxy errors](https://crawlrelay.com/docs/errors/socks5-proxy-errors/)
- [SSL: CERTIFICATE_VERIFY_FAILED](https://crawlrelay.com/docs/errors/ssl-certificate-verify-failed/)
- [SSL: WRONG_VERSION_NUMBER](https://crawlrelay.com/docs/errors/ssl-wrong-version-number/)

**Residential proxies with docs that cover the failure cases** CrawlRelay residential proxies from $0.50/GB, traffic that never expires. [See pricing](https://crawlrelay.com/pricing/) · [Quick start](https://crawlrelay.com/docs/)

---

CrawlRelay: CrawlRelay is a developer-first rotating residential and 4G/5G mobile proxy service for scrapers and AI data pipelines: non-expiring pay-as-you-go traffic from $0.50/GB, paid in crypto, with no ID upload. No KYC — no ID, no selfie, no documents. Pay in crypto.
