# 407 Proxy Authentication Required: Fix It

> 407 means your proxy wants credentials before forwarding the request. Fix it in curl, npm, pip, git and browsers, and learn how Proxy-Authenticate works.

Source: https://howhttpworks.com/status-codes/407
Last reviewed: 2026-10-04

> **TL;DR:** 407 comes from a proxy, not the website. It wants credentials in a `Proxy-Authorization` header before it will forward your request. Check which scheme `Proxy-Authenticate` asks for, then supply credentials the tool actually supports (Basic is common; NTLM/Kerberos usually need a helper).

## What it means

This is the proxy equivalent of [401](https://howhttpworks.com/status-codes/401). The proxy challenges you, you retry with credentials, the proxy forwards the request. RFC 9110 §15.5.8 requires the 407 to include `Proxy-Authenticate`.

```http
GET http://example.com/ HTTP/1.1
Host: example.com

HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="Corp Proxy"
Content-Type: text/html
Content-Length: 0
```

Retry with credentials:

```http
GET http://example.com/ HTTP/1.1
Host: example.com
Proxy-Authorization: Basic YWxpY2U6czNjcmV0
```

The value is `base64("alice:s3cret")`. Basic is not encryption. Over plain HTTP it is readable by anything on the path to the proxy, so only use it to a proxy you reach over a trusted network or TLS.

## HTTPS goes through CONNECT

For `https://` URLs, a client asks the proxy to open a tunnel with `CONNECT`, and the proxy usually challenges there:

```http
CONNECT api.example.com:443 HTTP/1.1
Host: api.example.com:443

HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Negotiate
Proxy-Authenticate: NTLM
Proxy-Authenticate: Basic realm="Corp Proxy"
```

This is why the symptoms look TLS-shaped even though it is an HTTP-level refusal. You will see:

```text
curl: (56) Received HTTP code 407 from proxy after CONNECT
```

```text
pip: ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 407 Proxy Authentication Required'))
```

Chrome shows `ERR_TUNNEL_CONNECTION_FAILED` when it cannot authenticate to the proxy, or prompts for credentials if it can.

## Diagnosis

1. Find out which proxy is in play: `env | grep -i proxy`, `git config --get http.proxy`, `npm config get proxy`, system settings, or a PAC file.
2. See what the proxy offers:

```bash
curl -v -x http://proxy.corp.example:8080 https://example.com/ 2>&1 | grep -i -E 'proxy-authenticate|HTTP/1.1 407'
```

3. Read the schemes. `Basic` works with username and password in most tools. `NTLM` and `Negotiate` (Kerberos) tie to your Windows login, and most CLI tools cannot do them natively.

## Fix it per tool

curl:

```bash
curl -x http://proxy.corp.example:8080 --proxy-user alice:s3cret https://example.com/

# NTLM / Negotiate
curl -x http://proxy.corp.example:8080 --proxy-ntlm --proxy-user alice:s3cret https://example.com/
curl -x http://proxy.corp.example:8080 --proxy-negotiate --proxy-user : https://example.com/
```

Environment variables (honoured by curl, pip, Go, Python requests and many others). Percent-encode special characters in the password:

```bash
export HTTPS_PROXY='http://alice:p%40ss%23word@proxy.corp.example:8080'
export HTTP_PROXY="$HTTPS_PROXY"
export NO_PROXY='localhost,127.0.0.1,.corp.example'
```

npm, pip and git:

```bash
npm config set proxy http://alice:s3cret@proxy.corp.example:8080
npm config set https-proxy http://alice:s3cret@proxy.corp.example:8080

pip install --proxy http://alice:s3cret@proxy.corp.example:8080 requests

git config --global http.proxy http://alice:s3cret@proxy.corp.example:8080
```

Credentials in config files and shell history are a leak risk. Prefer environment variables from a secrets store or an interactive prompt (`curl --proxy-user alice` prompts for the password).

If the proxy only offers NTLM or Kerberos, run a local forwarding helper (cntlm, px, or a corporate-provided agent), point your tools at `http://127.0.0.1:3128`, and let the helper authenticate upstream.

## If you operate the proxy

Squid with Basic authentication:

```text
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwords
auth_param basic realm Corp Proxy
acl authenticated proxy_auth REQUIRED
http_access allow authenticated
http_access deny all
```

Two operational traps. First, `Proxy-Authorization` is a hop-by-hop credential: the proxy must not forward it to the origin. Second, if your proxy does a 407 challenge on a plain HTTP request and your client is an API SDK that does not understand proxy auth, the SDK often surfaces an unhelpful JSON parse error because the 407 body is an HTML page.

## 407 vs 401 vs 403

| | 401 | 407 | 403 |
|---|---|---|---|
| Issued by | Origin | Proxy | Either |
| Challenge header | `WWW-Authenticate` | `Proxy-Authenticate` | none |
| Retry with | `Authorization` | `Proxy-Authorization` | credentials will not help |

## Related

- [401 Unauthorized](https://howhttpworks.com/status-codes/401): the origin-server version.
- [403 Forbidden](https://howhttpworks.com/status-codes/403)
- [Proxy-Authenticate](https://howhttpworks.com/headers/proxy-authenticate) and [Proxy-Authorization](https://howhttpworks.com/headers/proxy-authorization)
- [Via](https://howhttpworks.com/headers/via): shows proxies a request passed through.
- [502 Bad Gateway](https://howhttpworks.com/status-codes/502): what a proxy returns when it can reach no upstream.
