You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET6 Kestrel设仅HTTP/2时健康检查报TLS未协商HTTP/2错误

问题根因

这个报错和健康检查功能本身无关,是Kestrel配置错误导致所有请求都无法正常处理,核心问题有三个:

  • 协议与端点类型不匹配:你给端点默认配置了仅Http2协议,Kestrel的纯Http2模式默认要求必须通过TLS握手的ALPN扩展协商HTTP/2协议,但你绑定的是无TLS的明文HTTP地址,根本不存在TLS协商流程,自然会抛出协商失败错误。
  • Kestrel配置结构写错:你把Http端点节点写在了EndpointDefaults层级下,正确的端点配置应该放在Endpoints节点下,当前配置下你写的http://localhost:5020根本不会被Kestrel加载。
  • 健康检查UI额外兼容问题:你给UI配置的探测地址是相对路径,UI内部发起请求时默认走HTTP/1.1协议,就算Kestrel端配置正确,也可能出现探测失败的问题。
解决方案

根据你是否需要TLS选对应方案即可。

方案1:内网场景使用明文HTTP/2(h2c)

如果服务仅在内网服务间调用、不需要TLS加密,按如下修改:

  1. 修正Kestrel配置结构,将协议改为同时支持HTTP/1.1和HTTP/2(明文h2c需要通过HTTP/1.1的Upgrade头协商,必须开启HTTP/1.1支持):
"Kestrel": {
  "EndpointDefaults": {
    "Protocols": "Http1AndHttp2"
  },
  "Endpoints": {
    "Http": {
      "Url": "http://localhost:5020"
    }
  }
}
  1. 修正健康检查UI配置,写全探测端点的绝对地址,同时配置UI内部客户端支持明文HTTP/2请求:
services.AddHealthChecksUI(setup =>
{
    setup.SetEvaluationTimeInSeconds(60);
    // 替换为你实际的服务监听地址
    setup.AddHealthCheckEndpoint("Basic Health Check", "http://localhost:5020/healthz");
    // 配置探测客户端使用HTTP/2协议
    setup.ConfigureApiEndpointHttpMessageHandler = handler =>
    {
        if (handler is HttpClientHandler clientHandler)
        {
            clientHandler.DefaultRequestVersion = HttpVersion.Version20;
            clientHandler.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
        }
        return handler;
    };
}).AddInMemoryStorage();

*注意:所有主流浏览器都不支持明文HTTP/2(h2c),该方案仅适合服务间内部调用场景,如果需要给浏览器端提供访问能力,请选方案2的TLS模式。

方案2:公网/浏览器访问场景使用HTTP/2 over TLS

如果服务需要对外提供访问、走标准TLS加密,按如下修改:

  1. 修正Kestrel配置,绑定HTTPS端点和证书,保留仅HTTP/2配置:
"Kestrel": {
  "EndpointDefaults": {
    "Protocols": "Http2"
  },
  "Endpoints": {
    "Https": {
      "Url": "https://localhost:5021",
      // 开发环境可以去掉Certificate节点,直接使用.NET内置开发证书
      "Certificate": {
        "Path": "你的服务端证书.pfx",
        "Password": "证书导出密码"
      }
    }
  }
}
  1. 修正健康检查UI的探测地址为HTTPS绝对路径即可,不需要额外修改客户端协议配置:
services.AddHealthChecksUI(setup =>
{
    setup.SetEvaluationTimeInSeconds(60);
    setup.AddHealthCheckEndpoint("Basic Health Check", "https://localhost:5021/healthz");
}).AddInMemoryStorage();
额外建议

如果你的服务前面会挂Nginx、YARP等反向代理,不需要在Kestrel层强制HTTP/2,只需要在反向代理层做HTTP/2卸载,Kestrel和代理之间走HTTP/1.1通信即可,能避免h2c协商的各种兼容问题,稳定性更高。

验证方式

重启服务后先用命令行工具直接请求健康检查端点验证Kestrel配置是否生效:

# 明文场景用这个命令
curl --http2-prior-knowledge http://localhost:5020/healthz
# TLS场景用这个命令
curl --http2 https://localhost:5021/healthz

如果返回200状态码和健康检查结果,说明Kestrel端配置正常,再访问/healthcheck-ui页面,查看健康状态显示正常即全部配置完成。

内容的提问来源于stack exchange,提问作者Matt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 22:57:18