Hysteria2报错timeout: no recent network activity怎么办?官方排错清单逐条对照

连不上 Hysteria2 的时候,最常见的就是客户端日志里这一行:

1
failed to initialize client (connect error: timeout: no recent network activity)

这个报错信息量很少,只说明一件事:客户端把握手包发出去了,但是一直没有等到服务器的任何回应。它没有告诉你是服务器没开、端口被拦、还是配置不对。好在官方有一份排错文档,专门把这个报错的常见原因列了出来,这篇就按它逐条对照,再补上怎么判断方向的思路。

先看懂:什么情况下才是真的 timeout

官方排错文档里,除了这个超时报错,还有两个很容易混淆的报错:

  • authentication error, HTTP status code: 404:认证失败。
  • CRYPTO_ERROR ... tls: failed to verify certificate: x509: certificate signed by unknown authority:证书验证失败。

这两个报错有一个很有用的判断线索:它们能出现,说明客户端已经和服务器完成了 QUIC 握手,也就是 UDP 是通的,服务器确实回话了。只是后面一步(密码、证书)没过。这是我根据报错发生的位置做的推断,官方文档没有专门这样写,但逻辑上站得住。

所以排错方向可以先这样分:

你看到的报错 说明 往哪查
timeout: no recent network activity 收不到服务器回应 本文下面的清单
authentication error UDP 通了,认证没过 密码、连的是不是同一台服务器
证书验证错误 UDP 通了,证书没过 自签证书要不要开 insecure,SNI 对不对

后两种的处理看客户端导入连接里的参数对照。只有一直报 timeout,才需要看下面这些。

官方列出的 timeout 原因,逐条怎么查

1. 服务端没在运行,或者没在监听

先在服务器上看服务状态和监听端口:

1
2
3
systemctl status hysteria-server.service
ss -ulnp | grep hysteria
journalctl --no-pager -e -u hysteria-server.service

ss -ulnp 里的 -u 是只看 UDP,要能看到 hysteria 进程在你配置的端口上。如果没有输出,说明服务根本没起来,日志里通常能看到原因:证书申请失败、端口被占用、YAML 缩进错误等,详见config.yaml 最小配置。

2. 防火墙拦截了端口(系统和服务商两层)

官方文档特别说明要同时检查系统防火墙和服务商的安全组。这是最常见的原因:很多人只放行了 TCP,忘了 Hysteria2 用的是 UDP。

1
ufw status

系统防火墙里要有对应端口的 UDP 规则,比如 443/udp。服务商后台的安全组或者防火墙里,也要单独加一条 UDP 的入站规则。两层只要有一层没放行,客户端就是 timeout。用了端口跳跃的话,要放行整段端口,见端口跳跃配置。

3. 服务器地址或端口写错

官方列的第三条是"服务器地址或端口配置错误"。看起来是最低级的错误,但肉眼很难发现:多了空格、少了一位数、端口写成了 TCP 面板的端口。把客户端里的地址和端口,和服务端配置文件里的 listen 逐字对一遍。

4. 服务端监听在了访问不到的网络上

服务端 listen 如果只写了某个特定地址,比如只监听本机,外部访问就收不到。常规写法是 listen: :443,表示监听所有网卡。

5. 域名解析失败

客户端写的是域名的话,要确认这个域名真的解析到了你的服务器 IP:

1
dig +short 你的域名

返回的 IP 要和服务器 IP 一致。刚改过解析的话,可能还没生效,或者本地 DNS 缓存了旧记录。如果用了 Cloudflare 的橙色云朵代理,Hysteria2 是 UDP 协议,不能走这种代理,域名应该设成仅 DNS 解析(灰色云朵)。这条是我根据 Cloudflare 代理的一般特点提醒的,不在官方文档里,如果你没开代理可以忽略。

6. 混淆设置不一致

官方把"混淆设置错误"也列为 timeout 的原因。官方文档把它归在 timeout 下面,而不是认证错误,也就是说混淆对不上时,你看到的是超时,不会是明确的"密码错误"。至于为什么,我的理解是服务端无法把这种包当成正常的 QUIC 包处理,这是推断,官方没有展开解释。服务端配置里有 obfs,客户端必须有一模一样的类型和密码;服务端没有,客户端就不能填。

7. 旧版 Linux 内核(官方点名 CentOS 7)

官方文档明确写到:旧的 Linux 内核有已知问题,并且点名了 CentOS 7。如果你的服务器是 CentOS 7,上面几条都排除了还是 timeout,就要考虑换系统或升级内核,具体到哪个内核版本开始正常,官方没有写,我也没有核对,不乱给数字。

排查顺序建议

  1. 先看是不是真的 timeout:认证错误和证书错误,不用往防火墙查。
  2. 服务端:systemctl status 加 ss -ulnp,确认运行且监听 UDP 端口。
  3. 两层防火墙:系统防火墙和服务商安全组,都要有 UDP 规则。
  4. 地址、端口、域名解析:逐字对一遍,dig 看解析。
  5. 混淆:两端一致,要么都有要么都没有。
  6. 系统内核:CentOS 7 之类的旧系统,考虑升级。

想验证"UDP 包到底到没到服务器",可以在服务器上抓包看一眼,客户端发起连接的时候,有没有收到来自你客户端 IP 的包:

1
tcpdump -ni any udp port 443

端口换成你实际的。客户端连接时这里一个包都看不到,说明包在路上被拦了,问题在防火墙、安全组或者线路上;能看到包但客户端还是超时,就是服务端没处理或者回包出了问题,回头看日志和混淆设置。这是通用的排查思路,不是官方文档里的步骤。如果线路本身对 UDP 做了限制,Hysteria2 没有 TCP 备用通道,这点在优点和缺点那篇里讲过。

连上之后又断流,看哪里

如果一开始能连上,用着用着断了或者卡住,和初始化阶段的 timeout 不完全是同一个问题。官方客户端配置里有两个相关的参数,我核对了默认值:

  • maxIdleTimeout:默认 30 秒,客户端这么久没收到服务器的包,就认为连接已死。
  • keepAlivePeriod:默认 10 秒,客户端每隔这么久发一个包保活。

也就是说,如果线路上 UDP 包被丢掉或者被限速,超过 30 秒没有任何包回来,客户端就会判定断开。这两个参数官方不建议随便动,更值得先排查的是线路本身:这段时间有没有丢包、UDP 是不是在高峰期被限速。可以对照速度慢怎么办里的方法,用 TCP 协议在同一时间做对比,判断是线路问题还是配置问题。

如果你用的是端口跳跃,hopInterval 默认是固定 30 秒,如果新端口没有被放行,每次跳跃之后就会出现一次断连,这个也要留意。

这篇没有覆盖的

  • 不同客户端(Clash、sing-box、各种图形客户端)自己的报错写法不太一样,Clash 报"不支持的节点类型"是另一个问题,见Clash 报 unsupported proxy type hysteria2。
  • "被封"和"被 QoS"是线路层面的问题,官方文档没有给判断方法,我这里也没有可靠的依据去写,所以没有写成结论。

怀疑是线路被限制而不是配置问题,用对照测试缩小范围。