错误信息
code: 'ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE'
也可能输出为
- ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE
错误代码沿用 OpenSSL 的原因字符串:内置 OpenSSL 3.0 或 3.1 的 Node.js 版本报告 ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE(来自“sslv3 alert handshake failure”);内置 OpenSSL 3.5 的当前版本报告 ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE。使用 https.request() 时,同一个告警显示为“write EPROTO … SSL alert number 40”。
Node.js tls.connect / fetch — TLS alert 40 (handshake_failure) received from the server
含义
服务器用 TLS 告警 40(handshake_failure)回应了 Node.js 的 ClientHello,并关闭了连接。它找不到可接受的密码套件、密钥交换组和签名算法组合,或者要求提供客户端证书,而客户端没有发送。Node.js 根据 OpenSSL 的原因文本生成错误代码,因此代码中含有“SSL/TLS”。
原因
没有共同的密码套件
常见旧服务器只支持 RSA 密钥交换套件、3DES 套件或 RC4 套件,而 Node.js 的默认密码算法列表已不再包含这些套件。
服务器要求客户端证书(mTLS)
常见支付、银行和 B2B API 常常要求双向 TLS;如果 Agent 中没有配置 cert 和 key,TLS 1.2 服务器会以 handshake_failure 中止握手。
SNI 缺失或未知
偶见不设置 servername 而直接连接 IP 地址,或者连接 CDN 不提供服务的名称,都会导致一些前端服务器拒绝握手。
修复方法
- 1.
比较双方支持的内容
打印 Node.js 的默认密码算法列表,并枚举服务器支持的套件;如果没有交集,就必须更新服务器。
bash node -p "require('tls').getCiphers().length + ' suites; default list: ' + require('tls').DEFAULT_CIPHERS" nmap --script ssl-enum-ciphers -p 443 api.example.com # what the server accepts - 2.
发送客户端证书
在用于该 mTLS 端点的 Agent 上配置 cert 和 key(或 pfx)。
js // Mutual TLS: present the client certificate the server requires import https from "node:https"; import fs from "node:fs"; const agent = new https.Agent({ cert: fs.readFileSync("client.pem"), key: fs.readFileSync("client.key") }); https.get("https://mtls.example.com/", { agent }, (res) => res.resume()); - 3.
服务器管理员:提供现行的密码套件
TLS 1.3 加上采用 ECDHE 和 AES-GCM 或 ChaCha20-Poly1305 的 TLS 1.2,可以兼容所有仍在维护的 Node.js 版本。
text # Server side (nginx): TLS 1.3 + TLS 1.2 ECDHE with AEAD ciphers ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
相关错误
curl: (35) TLS connect error: error:0A000410:SSL routines::ssl/tls alert handsh…curl (OpenSSL backend)SSL routines:ssl3_read_bytes:ssl/tls alert handshake failureOpenSSL (client side)[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] ssl/tls alert handshake failurePython ssl module (OpenSSL)javax.net.ssl.SSLHandshakeException: (handshake_failure) Received fatal alert:…Java (JSSE)