sing-box Hysteria2 报 failed to parse certificate 怎么办?
简答:先检查 certificate 或 certificate_path 指向的内容是否是真实 PEM 证书,而不是公钥、私钥或截断文件。用 openssl x509 验证后,再排查 SNI、证书链和算法;insecure 不能修复证书解析失败。
定义:“failed to parse certificate”表示 sing-box 无法把 TLS 配置中的 certificate 或 certificate_path 内容解析为有效的 X.509 PEM 证书,不等同于证书不受信任或 SNI 不匹配。
先做这一项:确认 certificate_path 不是公钥文件
这是一个第三方使用指南站,以下步骤依据 sing-box 官方文档和公开 Issue 整理。遇到错误时,先保留完整日志和原配置副本,不要一开始就添加 insecure。
| 日志或现象 | 更可能属于哪一层 | 优先动作 |
|---|---|---|
failed to parse certificate | 证书内容无法解析 | 检查 PEM 头尾、文件类型、路径、编码和内容是否完整 |
panic: unknown value | 无效证书触发了错误处理缺陷 | 仍按证书无效处理,先更换真实证书或修正路径 |
x509: certificate signed by unknown authority | 证书可解析,但信任链不成立 | 检查 CA、证书链和信任库,确认后再考虑临时绕过 |
| 主机名不匹配或类似错误 | tls.server_name 与证书名称不一致 | 改为证书 SAN 中覆盖的域名,不要默认使用服务器 IP |
| 启用 Chrome QUIC 指纹后无法握手 | 证书算法兼容性问题 | 确认服务端是否使用 Ed25519,必要时改用 ECDSA 或 RSA |
公开 Issue #4658 的配置把由私钥导出的 public_key.pem 写入了 certificate_path。该文件是公钥,不是带有 X.509 证书结构的服务器证书,因此会出现 failed to parse certificate。可查看 Hysteria2协议:failed to parse certificate #4658 的原始配置。
真实证书通常包含 -----BEGIN CERTIFICATE----- 和 -----END CERTIFICATE-----。如果文件头是 BEGIN PUBLIC KEY、BEGIN PRIVATE KEY,或者内容是 HTML 错误页、裸 Base64、截断文本,就不能直接作为 certificate_path 使用。
按顺序执行:sing-box check、OpenSSL 和远端证书检查
- 记录当前程序和配置检查结果。在配置文件所在目录执行
sing-box version,再执行sing-box check -c config.json。如果这里已经报failed to parse certificate,说明问题发生在本地配置或证书读取阶段,还没有进入 Hysteria2 网络连接排查。 - 验证证书文件本身。命令要针对下载或生成的原始证书文件,不要针对私钥或公钥文件执行:
openssl x509 -in cert.pem -text -noout。能够输出 Subject、Issuer、Not Before 和 Not After,才说明文件至少能被 X.509 解析。 - 检查证书有效期和主题。如果证书已经过期,应重新签发或替换服务端证书;如果主题或 SAN 不包含客户端使用的域名,后续 TLS 校验仍会失败。
- 检查远端实际返回的证书。将域名和端口替换为实际服务端信息:
openssl s_client -connect example.com:443 -servername example.com -showcerts。重点观察服务端返回的证书、Issuer、有效期和证书链是否完整。 - 检查服务端日志和文件权限。确认服务端加载的是证书文件而不是公钥文件,私钥与证书属于同一对;Linux 或 macOS 上还要确认 sing-box 运行用户能够读取证书文件,Windows 上确认运行账户可以访问对应目录。
sing-box check 可以帮助发现配置和本地证书读取问题,但不能证明远端 Hysteria2 服务、UDP 端口、防火墙或服务端配置一定正常。若本地检查通过而连接仍失败,再继续查看连接日志与服务端日志。
另一个公开 Issue 说明,格式错误的 certificate 和 certificate_path 都可能触发 panic: unknown value,这属于错误处理路径异常,不代表证书已经有效。相关复现方式见 TLS certificate: panic("unknown value") instead of an error on an unparseable certificate #4347。
certificate 与 certificate_path 的正确写法
certificate_path 用于引用本地 PEM 文件,适合证书内容较长、需要单独替换或续期的场景;certificate 用于直接把 PEM 证书写入 JSON,必须正确处理换行。官方文档说明,这两个字段都要求 PEM 格式,文件修改后会自动重新加载。详见 Certificate - sing-box。
优先使用文件路径时,配置可以写成下面这样:
{"type":"hysteria2","tag":"hy2-out","server":"example.com","server_port":443,"password":"replace-with-real-password","tls":{"enabled":true,"server_name":"example.com","certificate_path":"./cert.pem"}}
Windows 路径建议使用正斜杠,例如 D:/sing-box/cert.pem。如果使用反斜杠,需要按 JSON 规则写成双反斜杠。路径指向的文件必须是真实证书,不能填入 private_key.pem、public_key.pem 或证书服务返回的网页文件。
如果直接内嵌证书,换行需要写成 JSON 转义形式:
{"tls":{"enabled":true,"server_name":"example.com","certificate":"-----BEGIN CERTIFICATE-----\nBASE64_CERTIFICATE_DATA\n-----END CERTIFICATE-----"}}
官方证书配置还支持单项字符串省略数组外层,也支持数组形式。无论使用哪种写法,内容都必须能通过 openssl x509 -in cert.pem -text -noout 验证。若拿到的是 DER 二进制证书,应先转换为 PEM,再填入路径;不要把二进制内容直接复制到 JSON。
解析失败、证书校验失败和 SNI 错误不要混在一起
这三类问题的修复方向不同。解析失败发生在 sing-box 读取证书内容时,常见原因包括误填公钥或私钥、PEM 头尾缺失、文件被截断、编码或路径错误;此时修改 server_name 或添加 insecure 通常不能解决。
证书校验失败则说明内容已经被解析,但系统或 sing-box 无法建立可信链。官方 TLS 文档将 insecure 定义为接受任何服务器证书,因此它只能作为确认“是否只是信任校验问题”的短期交叉验证,不能修复坏证书。相关字段说明见 TLS - sing-box。
临时配置可写成:
{"tls":{"enabled":true,"server_name":"example.com","insecure":true}}
只有在 OpenSSL 能解析服务端证书、你确认服务端使用自签证书或客户端暂时缺少对应信任链时,才适合短时间测试。连接恢复后,应重新配置正确的 CA 或证书,并删除 insecure。
SNI 问题则要检查 tls.server_name。官方文档说明,该字段用于验证返回证书上的主机名,也会用于 ClientHello 的虚拟主机识别;应填写证书 SAN 覆盖的域名。若服务端证书只覆盖域名,配置却填服务器 IP,证书可能可以解析,但握手会因主机名不匹配失败。
如果启用了 Hysteria2 的 Chrome QUIC 指纹模仿,还要检查服务端证书算法。官方 Hysteria2 文档指出,Chrome 不声明支持 Ed25519,使用 Ed25519 证书的服务端可能无法完成握手,应改用 ECDSA 或 RSA 证书。这个阶段属于握手兼容性问题,不是 PEM 解析失败。具体说明见 sing-box Hysteria2 出站配置文档。
版本核对与最终自查清单
截至 2026-10-24,Releases 标记为 Latest 的是 1.14.4。遇到问题时,先记录 sing-box version、完整日志、配置中的 TLS 片段和 OpenSSL 输出,再用同一份配置对比稳定版。版本更新可能改变错误表现,但不能替代证书内容修复;发布列表见 SagerNet/sing-box Releases。
- 配置中的
certificate或certificate_path是否真的指向 X.509 PEM 证书。 - 文件是否包含完整的证书头尾,是否误填公钥、私钥、DER、HTML 或截断内容。
sing-box check -c config.json是否通过,路径是否因当前工作目录不同而失效。openssl x509 -in cert.pem -text -noout是否能够读出主题、签发者和有效期。tls.server_name是否与证书 SAN 中的域名一致。- 服务端返回的证书链是否完整,服务端日志是否显示加载了正确的证书和私钥。
- 是否只把
insecure用作短期验证,并在恢复后删除。 - 如果启用 Chrome QUIC 指纹模仿,服务端是否使用了不兼容的 Ed25519 证书。
常见问题
把 public_key.pem 填到 certificate_path 为什么不行?
public_key.pem 通常只是从私钥导出的公钥,不是包含 X.509 元数据的服务器证书。certificate_path 要读取可解析的 PEM 证书,先用 openssl x509 验证,无法解析就应重新获取真实证书。
failed to parse certificate 和证书不受信任是一回事吗?
不是。failed to parse certificate 表示内容无法解析,常见原因是文件类型、格式或路径错误;证书不受信任表示内容已经解析,但 CA 或信任链校验失败。insecure 不能修复坏证书。
certificate 和 certificate_path 应该选哪个?
本地已有 PEM 文件时优先使用 certificate_path,便于替换、检查和自动重新加载;只有需要把证书直接写入 JSON 时才使用 certificate,并正确处理换行转义。
为什么 server_name 不能随便写服务器 IP?
TLS 会使用 server_name 验证服务端返回证书上的主机名。若证书只覆盖域名而配置写成 IP,证书虽然可能可以解析,但握手仍会因主机名不匹配失败。
修好证书后仍然无法连接怎么办?
先用 openssl s_client 检查远端证书链和 SNI,再查看服务端日志、UDP 端口、防火墙、密码和证书算法。若启用 Chrome QUIC 指纹模仿,还要检查服务端是否使用 Ed25519 证书。