代理错误代码大全:HTTP、curl、Python、Node 与 Chrome
代理错误代码一页查全:407、429、502、503、504 来自代理还是网站,curl 退出码,Python、Node 和 Chrome 的代理报错,以及先查哪里。
代理错误代码有两个来源:一是代理本身,它拒绝为你连接,或者连不上网站;二是网站,它通过代理回应你。407 一定来自代理;429、403、502、503 则两边都可能发。先弄清是哪一边发的,再到下面的表里查你的工具打印出的那条报错。
这是一份代理报错大全,供随时查阅。每一行给出一句话的含义、第一步该查什么,以及讲得更深的那篇文章。这里引用的每一条报错,都是我们在自己机器上对着本地测试代理复现出来的,用的是 curl 8.5、Python requests 2.34、Node.js 22 搭配 undici 8.11 和 axios,以及 Chrome for Testing 153。不同版本的措辞会略有变化,按关键词对照即可。
报错是代理发的,还是网站发的?
访问 https 网站时,客户端先请代理打开一条 CONNECT 隧道。这个请求由代理自己回答:200 表示“隧道已打开”,否则就是一个错误状态码。只有拿到 200 之后,网站才有机会说话。所以:
- CONNECT 阶段的错误来自代理,网站根本没见到你。
- 隧道建立成功之后的错误来自网站,只是经过了代理。
curl 可以把两边的回答并排打印出来:
curl -s -o /dev/null -x "http://USERNAME:PASSWORD@HOST:PORT" \
-w 'proxy said %{http_connect}, site said %{http_code}\n' \
https://api.ipify.org
在我们的测试里,代理拒绝开隧道时打印 proxy said 429, site said 000;隧道正常、网站在限流时打印 proxy said 200, site said 429。你的代码也会以自己的方式体现这种区别:
| 工具 | 代理拒绝开隧道 | 网站返回错误 |
|---|---|---|
| curl | 退出码 56,CONNECT tunnel failed, response 429 |
退出码 0,状态码在 %{http_code} 里 |
| Python requests | ProxyError,里面有 Tunnel connection failed: 429 Too Many Requests |
正常的响应,r.status_code == 429 |
| Node.js undici | TypeError: fetch failed,往下两层 cause 是 Proxy response (429) !== 200 when HTTP Tunneling |
正常的响应,res.status === 429 |
| Chrome | net::ERR_TUNNEL_CONNECTION_FAILED |
网站自己的错误页面 |
有一个例外:普通 http:// 网址没有隧道,代理的错误会作为一个普通响应返回。requests 把代理的 407 当成 r.status_code == 407 返回,没有抛异常。想把两边分开看,就用 https:// 网址测试。
HTTP 代理错误:400、403、407、429、502、503、504
| 状态码 | 如果是代理发的,通常表示 | 如果是网站发的,通常表示 | 先查 | 延伸阅读 |
|---|---|---|---|---|
| 400 | 看不懂客户端发来的内容:代理字符串格式有误,或协议不对 | 你的请求本身格式有误 | 代理字符串和协议头 | 代理格式 |
| 403 | 不肯转发这个请求:服务未生效,或目标被拒绝 | 网站拒绝这个出口 IP 或你的访问方式 | 先查服务状态,再查目标 | 爬虫被封 |
| 407 | 要求登录,但不接受你的凭据 | (网站不发这个,网站用 401) | 服务页面上的用户名和密码 | 解决 407 |
| 429 | 代理这一端的限额,前提是服务商设了限额 | 网站在对你限流 | 先查是哪一边发的,再查请求速度 | 解决 429 |
| 502 | 连不上网站:域名不对、连接被拒 | 网站自己的网关出错 | 用同一个代理访问 https://api.ipify.org |
超时错误 |
| 503 | 暂时无法为你服务 | 网站过载,或它的防机器人系统在应答 | 退避后稍后重试 | 重试 |
| 504 | 网站没有及时回应代理 | 网站的上游超时了 | 直连能否打开这个网站 | 超时错误 |
代理一栏中的 403、407、429、502 和 503,我们让测试代理用这些状态码回应 CONNECT 逐一复现过,每个客户端的表现都和上面的规律一致。通过正常的代理访问一个拼错的域名,得到的是代理发来的 502,而不是 DNS 错误,因为域名是代理去解析的。
curl 代理报错:按退出码查
| 退出码 | 我们看到的报错 | 含义 | 先查 |
|---|---|---|---|
| 5 | Could not resolve proxy: HOST |
代理主机名解析不了 | HOST 有没有错字,或你的 DNS |
| 5 | Unsupported proxy syntax in '...': Port number was not a decimal number between 0 and 65535 |
curl 读不懂这个代理字符串 | 密码里的符号,或用了冒号分隔的行 |
| 7 | Failed to connect to HOST port PORT after 0 ms: Couldn't connect to server |
没有任何东西接受连接 | HOST 和 PORT,以及服务是否有效 |
| 7 | Unsupported proxy scheme for 'ftp://...' |
curl 不支持用这个协议连代理 | 改用 http:// |
| 28 | Failed to connect to HOST port PORT after 3006 ms: Timeout was reached |
完全没有回应 | 你所在网络的防火墙 |
| 28 | Connection timed out after 4005 milliseconds |
连上了,但隧道或握手没有完成 | 代理或网站,见超时错误一文 |
| 28 | Operation timed out after 5006 milliseconds with 0 bytes received |
隧道已建立,网站一直不说话 | 网站,或出口较慢 |
| 35 | OpenSSL/3.0.13: error:0A00010B:SSL routines::wrong version number |
对着不是 TLS 的东西说了 TLS | 该写 http:// 的地方写成了 https://,或端口不对 |
| 56 | CONNECT tunnel failed, response 407(或 403、429、502、503) |
代理以这个状态码拒绝开隧道 | 看上面的 HTTP 表 |
| 56 | Recv failure: Connection reset by peer |
连接被切断 | 重试,再换个网络试试 |
| 56 | Proxy CONNECT aborted |
代理没有回应就关闭了连接 | 重试,再检查服务 |
| 60 | SSL certificate problem: self-signed certificate |
网站证书没有通过校验 | 见下面的证书一节 |
| 97 | Received invalid version in initial SOCKS5 response. |
用 socks5:// 连了一个 HTTP 代理 |
改用 http://,或在控制台里把该代理设为 SOCKS5 |
表里的毫秒数是我们那几次运行的结果,你的会不一样。注意 28 出现了三次:看数字后面的文字,才知道是哪个阶段超时;怎么用 curl -w 把时间拆开,见代理超时错误。
Python requests 代理报错
| 异常 | 报错里的关键内容 | 含义 |
|---|---|---|
ProxyError |
NewConnectionError ... [Errno 111] Connection refused |
HOST:PORT 上没有服务在监听 |
ProxyError |
NameResolutionError ... Failed to resolve |
代理主机名解析不了 |
ProxyError |
ConnectTimeoutError ... timed out |
代理始终没有回应连接 |
ProxyError |
OSError('Tunnel connection failed: 407 Proxy Authentication Required') |
代理拒绝开隧道,数字就是它的状态码 |
ProxyError |
Your proxy appears to only use HTTP and not HTTPS |
代理 URL 以 https:// 开头,改用 http:// |
ReadTimeout |
Read timed out. |
连上了,但没有按时得到回应 |
ConnectionError |
ConnectionResetError(104, 'Connection reset by peer') |
连接被切断 |
ConnectionError |
RemoteDisconnected('Remote end closed connection without response') |
代理没有回应就关闭了连接 |
SSLError |
[SSL: WRONG_VERSION_NUMBER] wrong version number |
对着非 TLS 端口说了 TLS |
SSLError |
CERTIFICATE_VERIFY_FAILED |
网站证书没有通过校验 |
InvalidURL / InvalidProxyURL |
Failed to parse / It is malformed |
这个代理字符串不是 requests 能读的 URL |
这张表里的坑:设置了代理时,连接代理超时会以 ProxyError 的形式出现,而不是 ConnectTimeout。只写 except requests.ConnectTimeout 是接不住的。把 ProxyError 也一起捕获,并阅读 “Caused by” 后面的部分。
Node.js 代理报错:ECONNREFUSED、ECONNRESET、ETIMEDOUT
用 undici 的 fetch 时,每一种网络故障都是 TypeError: fetch failed。真正的原因在 error.cause 里,有时还要再往下一层,所以把整条链打出来:
function rootCause(error) {
while (error.cause) error = error.cause;
return typeof error.code === 'string' ? `${error.code}: ${error.message}` : error.message;
}
| 链条最底层的代码或信息 | 含义 |
|---|---|
ECONNREFUSED: connect ECONNREFUSED HOST:PORT |
代理地址上没有服务在监听 |
ENOTFOUND: getaddrinfo ENOTFOUND HOST |
代理主机名解析不了 |
UND_ERR_CONNECT_TIMEOUT: Connect Timeout Error (attempted address: ...) |
连代理或开隧道时没有按时得到回应 |
UND_ERR_ABORTED: Proxy response (407) !== 200 when HTTP Tunneling |
代理拒绝开隧道,数字就是它的状态码 |
UND_ERR_SOCKET: other side closed,上一层是 UND_ERR_PRX_CONN: Proxy Connection failed |
代理没有回应就关闭了连接 |
TimeoutError: The operation was aborted due to timeout |
你自己设的 AbortSignal.timeout 先到了 |
ECONNRESET: read ECONNRESET |
连接被切断 |
ERR_SSL_WRONG_VERSION_NUMBER |
对着非 TLS 端口说了 TLS,常见于 https:// 开头的代理 URL |
DEPTH_ZERO_SELF_SIGNED_CERT、ERR_TLS_CERT_ALTNAME_INVALID |
网站证书没有通过校验 |
axios 配合 https-proxy-agent 时,报出的代码更直接。在我们的测试里,它给出的是和上面一样的 ECONNREFUSED 和 ECONNRESET;登录被拒时是 AxiosError: Request failed with status code 407;代理地址始终不回应时是 connect ETIMEDOUT。最后这个等了两分多钟,那是操作系统自己的上限,所以请自己设一个超时。超时写在哪里,见 Node.js 和 axios 教程。
Chrome 的 net::ERR_ 代理错误
| 代码 | 含义 |
|---|---|
ERR_PROXY_CONNECTION_FAILED |
Chrome 连不上代理:主机或端口不对,或者忘了关的系统代理 |
ERR_TUNNEL_CONNECTION_FAILED |
代理拒绝或无法打开隧道,登录失败也算在内 |
ERR_NO_SUPPORTED_PROXIES |
在 --proxy-server 里写了登录信息,或者协议头不认识 |
ERR_PROXY_AUTH_UNSUPPORTED |
代理要求一种 Chrome 不支持的登录方式 |
ERR_SOCKS_CONNECTION_FAILED |
用 socks5:// 指向了 HTTP 代理 |
每个代码的含义、我们复现出的原因,以及 Chrome 把相关设置藏在哪里,见 Chrome 代理报错。
走代理时的证书错误
使用 CONNECT 隧道的 HTTP 代理只负责转发加密后的字节,并不读取内容,网站证书由你的客户端端到端校验。所以走代理时出现证书错误,意思是隧道另一端的东西没有出示一张你的客户端信任、且与这个域名相符的证书。先检查你请求的域名和端口。如果每个网站都以同样的方式失败,可能是你自己网络上的某个东西在检查 TLS,比如安全软件或公司网关。关闭证书校验只是把问题藏起来,并没有回答它,所以只在你自己能控制的本地测试里这么做。
失败的请求要花钱吗?
这取决于服务商,值得在写重试循环之前弄清楚。在我们这里,诚信页面是这样写的:“连接失败(超时、连接重置,以及我们自己网关返回的错误,比如 407 或 502)计零,但照样显示出来,标成免费。”网站发回来的任何东西,包括 429 和 5xx 页面,都算流量,所以重试一次要花掉那个响应的字节,通常不多。重试也要花时间,哪些错误值得再试一次,见重试时怎么不浪费流量。
常见问题
哪些代理错误代码说明我的登录信息不对? 代理发的 407。它在 curl 里是退出码 56 加 “response 407”,在 requests 里是提到 407 的 ProxyError,在 undici 里是 “Proxy response (407)”。在 Chrome 里它会变成 ERR_TUNNEL_CONNECTION_FAILED。
502 是代理的错吗? 不一定。代理发的 502 通常表示它连不上网站。如果通过同一个代理能打开 https://api.ipify.org,就去查目标网站。
为什么超时了 requests 却报 ProxyError? 因为故障发生在连接代理的时候。底层的 ConnectTimeoutError 就在报错信息里。
下一步
把这一页放在日志旁边随时对照;遇到这里没有的报错,就把工具、版本和完整报错(去掉密码)贴到 Discord。如果你还在挑选方案,价格页面列出了每个产品,小额充值就足够对着你自己的目标把这一页的检查都跑一遍。