文章

遇到 421 Misdirected Request?SNI、Host 与连接复用怎么查

HTTP 421(Misdirected Request)表示服务器不愿或不能为这次请求的目标提供权威响应。排查时应先核对完整 URL、请求名称与连接上下文,再检查连接复用;它本身不是“节点带宽不足”或“代理密码错误”的证明。

本文适用于通过 VPN、代理或直连访问 HTTPS 页面时收到 421 的情况。需要区分“已经收到 HTTP 响应”和“TLS 握手就失败”:两者应查的阶段不同。

421 到底是谁拒绝了什么?

RFC 9110 第 15.5.20 节说明,源站或代表源站的网关可以用 421 拒绝与其服务范围、连接上下文不匹配的目标 URI。标准还规定,正向代理不应自行生成 421;但它可以转发上游的响应。

因此,“开代理时看见 421”并不能单独证明响应由代理节点产生。应结合发生阶段及对应日志,检查是访问的网站、入口网关,还是其他环节返回了这个结果。错误页中的一个产品名称,也不足以还原整条链路。

SNI、Host 和目标 IP 不是同一项

信息 所在阶段 主要用途
目标 IP 与端口 建立连接 决定连接到哪个网络端点
TLS SNI TLS 握手 向 TLS 服务端说明希望访问的服务器名称
HTTP/1.1 Host HTTP 请求 标识请求所面向的主机及相应端口信息
HTTP/2 :authority HTTP 请求控制数据 传递目标 URI 的 authority 部分

SNI 位于 ClientHello 中,见 RFC 6066 第 3 节。HTTP/2 的 :authority 与 Host 的关系则见 RFC 9113 第 8.3.1 节。它们分属不同层次,不能把“手动改一个 Host 请求头”理解成同时改好了 SNI、证书验证和后端映射。

普通访问先保留网站原始域名。不要用“把网址换成 IP,再跳过证书检查”替代诊断:这会改变请求条件,无法说明原域名为什么收到 421。若实际报错是证书名称不匹配,应先按时间、SNI 与信任链检查处理。

为什么 HTTP/2 连接复用也会遇到 421?

RFC 9113 第 9.1.1 节允许在满足服务权威性等条件时,用已有连接处理不同 URI authority 的请求;HTTPS 还需要证书对目标主机有效。标准同时指出,某些使用 SNI 选择后端的部署,可能在复用时把请求送到不合适的源站。

一个具体例子来自 Apache mod_http2 文档:多个虚拟主机共享证书时,若相关 TLS 协议、密码套件或客户端验证设置不一致,可能返回 421。这说明“证书涵盖两个域名”不等于两者在同一连接上一定具有兼容配置。

这是特定实现的例子,不代表所有 421 都来自 Apache,也不意味着看到 h2 就能确定是连接复用故障。

按四步收集能解释问题的证据

1. 找到真正失败的请求

记录完整域名、端口、请求方法、状态码和时间。首页、登录接口、脚本可能属于不同主机,不要把首页成功当成所有请求成功。

在浏览器开发者工具的 Network 中查看失败行的请求地址和协议;操作可结合本站HTTP/3、HTTP/2 与代理路径核对。反馈时去掉 URL 令牌、Cookie 和身份凭据。

2. 建立新连接对照

对于普通页面 GET,可以在保存必要内容后完全退出浏览器,再重新打开同一地址,记录首次访问与后续访问的差异。普通刷新或清缓存不应被当成“所有旧连接都已经关闭”。

标准允许收到 421 的客户端使用不同连接重试,但诊断时仍需明确请求性质。付款、发帖或其他提交失败,应先检查业务是否完成,不把刷新按钮当作无条件重试工具。

3. 有条件地比较 HTTP 版本

Windows 可先运行 curl.exe --version。只有输出的 Features 包含 HTTP2 时,再做下面的两轮测试。选择一个无需登录的普通 HTTPS GET 页面,并确认 curl 与浏览器采用可比较的代理路径;命令行接入问题可参考终端代理排查。

$testUrl = Read-Host '输入要核对的普通 HTTPS 页面 URL'
foreach ($protocolOption in @('--http1.1', '--http2')) {
    curl.exe -q --silent --show-error --connect-timeout 10 --max-time 30 `
        $protocolOption --output NUL `
        --write-out "option=$protocolOption status=%{response_code} http=%{http_version} connect=%{http_connect}`n" $testUrl
}

参数与输出依据 curl 官方手册:status 是最后传输的响应码,http 是实际使用的 HTTP 版本,connect 是代理 CONNECT 的响应码。没有发起 CONNECT 时,不能把该项当成源站结果。

--http2 对 HTTPS 是发起协商,不保证最终使用 HTTP/2,必须看 http。两次 curl 是独立进程、各访问一个 URL,不会重现浏览器跨域复用的完整历史;它们只提供新连接下的对照。若工具不支持 HTTP/2,记录这一限制即可,不要把参数报错当成网站 421。

4. 根据差异决定交给谁继续查

观察结果 可继续调查的方向
浏览器出错,新连接恢复 原连接状态、复用与入口配置;尚不能确定根因
确认 h2 返回 421,HTTP/1.1 正常 虚拟主机、TLS 配置及协议相关处理
两种版本均返回 421 URL、入口及服务端映射,不局限于 HTTP/2
仅某条代理路径异常 对照实际出站、解析与所到入口,不能只归因于节点

以上是线索,不是单项判定。一次最终 200 也不足以证明之前没有出现过 421,客户端可能进行过恢复处理。

站长需要核对哪些配置?

有服务端权限时,应沿“TLS 入口 → 虚拟主机 → 反向代理 → 后端”核对预期映射,确认请求的 scheme、authority 与握手上下文是否被正确处理,并把日志时间与失败请求对应起来。涉及共享证书的多站点部署,可优先检查前述实现文档中的 TLS 一致性要求。

普通读者无需为了访问一个网站修改这些服务端配置。提供一份可复现记录,通常比长期关闭 HTTP/2 或反复更换节点更有帮助。

时间/请求方法/目标主机 原路径与协议 新连接结果 对照协议与结果 已脱敏错误或请求标识
待填写 待填写 待填写 待填写 待填写

资料核对日期:2026-10-30。本文未实测特定服务,示例不关闭证书验证;排查结论以实际响应、连接条件和对应日志为准。

评论

搜索文章

正在加载搜索…