.NET SslStream / HttpClient.NET
错误信息
Cannot determine the frame size or a corrupted frame was received.
也可能输出为
- System.Security.Authentication.AuthenticationException: Cannot determine the frame size or a corrupted frame was received.
.NET Core、.NET 5~10 和 .NET Framework 中的文本相同。HttpClient 会把它包装在外层异常“The SSL connection could not be established, see inner exception.”中。
.NET SslStream / HttpClient — AuthenticationException when the peer's reply is not a TLS record
含义
SslStream 期望读到 TLS 记录头,收到的字节却构不成记录头,因此连下一帧有多长都无法判断。对端在该端口上使用的不是 TLS——典型情况是用 https:// 访问了明文 HTTP 端点(“HTTP/1.1 400 …”),或者对端协议以明文开始通信。
原因
用 https:// 访问明文 HTTP 端口
常见用 https:// URL 调用服务的 HTTP 端口(或 sidecar、指标或健康检查端口)。
Kestrel 在你使用的端口上监听的是 HTTP
常见launchSettings.json 或 ASPNETCORE_URLS 在客户端当作 HTTPS 的端口上配置了 http://,这是 5xxx 与 7xxx 开发端口之间常见的混淆。
把明文代理配置成了 TLS 代理
偶见代理只接受来自客户端的明文 HTTP,却配置了 https:// 代理地址。
修复方法
- 1.
检查端口使用的协议
如果端口以明文 HTTP 应答,就改用 HTTPS 端口或 http://。
bash curl -si http://api.example.com:8080/ | head -1 # answers over plain HTTP? - 2.
使用 Kestrel 监听的 HTTPS URL
检查 applicationUrl 或 ASPNETCORE_URLS,并调用其中的 https:// 地址及其端口。
json { "profiles": { "https": { "commandName": "Project", "applicationUrl": "https://localhost:7001;http://localhost:5001" } } } - 3.
邮件:STARTTLS 端口需要使用 STARTTLS
使用 MailKit 时,在 587 端口上用 SecureSocketOptions.StartTls,SslOnConnect 只用于 465 端口。
csharp // MailKit: STARTTLS on 587, implicit TLS (SslOnConnect) on 465 await smtp.ConnectAsync("mail.example.com", 587, MailKit.Security.SecureSocketOptions.StartTls);