.NET HttpClient.NET
错误信息
The SSL connection could not be established, see inner exception.
也可能输出为
- System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
从 .NET Core 3.x 到 .NET 10,该文本保持不变。框架(Refit、gRPC、Azure SDK)可能会再包装一层,因此内部异常可能在下面两三层。
.NET HttpClient — HttpRequestException wrapping the AuthenticationException or IOException of the TLS handshake
含义
这是 HttpClient 在连接时遇到任何 TLS 失败都会使用的通用包装。消息本身不包含任何诊断信息:真正的原因在 InnerException 中(指明证书问题的 AuthenticationException,或者来自传输层的 IOException)。只记录 e.Message 会把原因隐藏起来;应记录整个异常链。
原因
证书验证失败
常见不受信任或不完整的证书链、过期的证书或主机名不匹配:内部的 AuthenticationException 会指出对应的 X509ChainStatus 或 SslPolicyErrors 值。
没有共同的协议或加密算法
偶见仍使用 TLS 1.0/1.1 或过时密码套件的老旧服务器;在 Linux 上,内部异常会显示 OpenSSL 原因。
连接不是 TLS,或者被切断
偶见明文 HTTP 端口、代理或防火墙关闭了连接,或者服务器重置了握手。
修复方法
- 1.
记录完整的异常链
逐层遍历 InnerException(或者记录整个异常对象,而不只是 Message),才能看到真正的原因。
csharp catch (HttpRequestException e) { for (Exception? ex = e; ex != null; ex = ex.InnerException) logger.LogError("{Type}: {Message}", ex.GetType().FullName, ex.Message); } - 2.
根据内部消息找到对应原因
每条内部消息都对应不同的修复方法;下方的相关条目会逐一介绍。
text Inner exception -> look at "...errors in the certificate chain: UntrustedRoot / PartialChain" -> trust store, server chain "...errors in the certificate chain: NotTimeValid" -> dates, clock "...validation procedure: RemoteCertificateNameMismatch" -> host name vs SAN "Cannot determine the frame size or a corrupted frame was received." -> port is not TLS "Received an unexpected EOF or 0 bytes from the transport stream." -> server/proxy closed "SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL." -> protocol/cipher (Linux)
相关错误
The remote certificate is invalid because of errors in the certificate chain: U….NET SslStream / HttpClientThe remote certificate is invalid according to the validation procedure: Remote….NET SslStream / HttpClientCannot determine the frame size or a corrupted frame was received..NET SslStream / HttpClientReceived an unexpected EOF or 0 bytes from the transport stream..NET SslStream / HttpClientSSL Handshake failed with OpenSSL error - SSL_ERROR_SSL..NET on Linux (SslStream over OpenSSL)