该错误本质是TLS握手失败,核心原因是Nginx收到非TLS数据包,常见于proxy_pass配置的https协议与后端实际运行的HTTP服务不匹配,或TLS版本/配置严重不兼容;需优先确认后端是否真支持HTTPS、SNI是否启用、会话复用是否冲突,并通过tcpdump抓包验证协议真相。

这个错误本质是 TLS 握手失败,核心原因是 Nginx 收到了一个它无法识别为有效 TLS 记录的数据包——常见于“本该是 HTTPS 的地方实际跑着 HTTP”,或协议版本/配置严重不匹配。排查要从“谁在跟谁说话”入手,而不是只盯证书。
检查 upstream 是否真支持 HTTPS
最常被忽略的一点:你在 proxy_pass 里写了 https://127.0.0.1:8081,但后端服务(比如 Spring Boot、Node.js 或 Java 应用)监听的 8081 端口很可能只启用了 HTTP,根本没配 TLS。
- 用
curl -v http://127.0.0.1:8081/health测试是否能通;再试curl -v https://127.0.0.1:8081/health—— 如果后者报curl: (35) error:1408F10B或连接拒绝,就说明后端没开 HTTPS - 确认后端是否真的监听了 TLS 端口(如 8443),且证书私钥配置正确;若只是普通 Web 服务,
proxy_pass应改为http://127.0.0.1:8081 - 特别注意 Docker 场景:容器内服务暴露的是 HTTP 端口,Nginx 却试图以 HTTPS 连接它,必然触发此错误
验证 Nginx 反向代理 SSL 配置合理性
即使后端支持 HTTPS,Nginx 的代理层 SSL 参数也可能导致握手异常,尤其是会话复用和 SNI 设置。
- 强制关闭上游 SSL 会话复用:
proxy_ssl_session_reuse off;—— 这是解决短时高频请求下 502 + 1408F10B 的关键项 - 确保启用 SNI(尤其当上游是多域名共享 IP 的 HTTPS 服务):
proxy_ssl_server_name on; - 避免混用不安全的 TLS 版本:在 upstream 上下文中添加
proxy_ssl_protocols TLSv1.2 TLSv1.3;,禁用老旧的 SSLv3/TLSv1.0
排除客户端误连非 HTTPS 端口
错误日志中出现 SSL3_GET_RECORD:wrong version number,有时根本不是代理问题,而是客户端直接把 HTTPS 请求发到了本应处理 HTTP 的端口上。
- 检查 Nginx 的
listen 80块有没有意外配置了ssl参数(比如漏删了ssl on;或ssl_certificate) - 查看 access log 中出错请求的原始协议:如果日志显示
"\x16\x03\x01..."开头(TLS 握手包特征),但目标 server block 是 listen 80 且无 SSL,说明浏览器或 curl 错误地向 HTTP 端口发了 HTTPS 请求 - 典型表现:访问
https://example.com正常,但https://example.com:80或通过 IP 直连 HTTPS 端口失败,往往就是端口与协议错配
快速定位:用 tcpdump 抓包比猜更准
光看日志容易误判方向。直接抓 Nginx 与 upstream 之间的流量,能一眼看清协议真相。
- 在 Nginx 服务器执行:
tcpdump -i lo port 8081 -w upstream.pcap(假设 upstream 是本地 8081) - 复现一次失败请求,然后用 Wireshark 打开 pcap 文件,过滤
tls或查看数据包明文内容 - 如果看到 Client Hello 后 upstream 立即 RST,或响应的是 HTTP 200 而非 TLS Server Hello,就坐实了 upstream 不支持 HTTPS


















