Diagnosing proxy status codes 407 and 403
Updated 2 min read
A 407 always comes from the proxy. A 403 can come from the proxy or from the website behind it, and the fix is different for each. Establish the sender before you change anything.
Step 1: identify the sender
Print the proxy's answer to the tunnel request separately from the website's answer:
curl -sS -o /dev/null -x "http://USERNAME:PASSWORD@HOST:PORT" \
-w "proxy=%{http_connect} site=%{http_code}\n" TARGET_URL
| Output | Sender | Go to |
|---|---|---|
proxy=407 |
The proxy, before any tunnel opened |
Step 2 |
proxy=403 |
The proxy, before any tunnel opened |
Step 3 |
proxy=200 site=403 |
The website, after the tunnel opened |
Step 4 |
With curl -v, the boundary is the proxy's 200 reply to the CONNECT request. A status printed before it came from the proxy; a status printed after it came from the website.
Step 2: 407 Proxy Authentication Required
The proxy received no credentials it accepts. Check, in order:
- The username and password match the Connection card on the proxy's page, character for character, with no trailing space or line break.
- Reserved characters in the password are percent-encoded inside the URL:
@as%40,:as%3A,/as%2F,#as%23. - The client actually sends the credentials. Some clients send them only after a first 407, so a single 407 followed by success is normal.
- If you rely on the IP allowlist instead of credentials, the address you connect from is on the list. See Authenticating by IP allowlist.
- The proxy is Active.
- The password was not replaced recently. After Generate a new password, the old one stops working at once.
Step 3: 403 from the proxy
The proxy refused the connection before forwarding it. Check:
- The source address against the allowlist, if you use one. Whether an unlisted address is answered with 407 or 403, the remedy is the same: add the address you actually connect from.
- The proxy's status on its page. An expired proxy does not carry traffic.
- The host and port belong to the proxy you are testing, not to another one.
Step 4: 403 from the website
The proxy worked. The website refused the request from that exit address or for that request pattern.
- Retry from a different exit address.
- Lower the request rate and send the headers a normal browser would send.
- If the refusal persists across addresses, collect the evidence in Reporting a blocked target: required information.
If the sender is still unclear, send support the curl -v output with the password replaced by REDACTED.