使用Nodemailer对接mail.com SMTP时出现版本号错误的解决咨询
Nodemailer配置mail.com SMTP时SSL版本错误的问题解决
问题详情
配置Nodemailer通过mail.com的SMTP服务器发送邮件时,触发以下SSL相关错误:
Error: AC650000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:c:\ws\deps\openssl\openssl\ssl\record\ssl3_record.c:355: { library: 'SSL routines', reason: 'wrong version number', code: 'ESOCKET', command: 'CONN' }
当前使用的Nodemailer配置代码:
import nodemailer from 'nodemailer'; import dotenv from 'dotenv'; import path from 'path'; // Load environment variables from .env file dotenv.config({ path: path.resolve('.env') }); console.log('EMAIL_USERNAME:', process.env.EMAIL_USERNAME); console.log('EMAIL_PASSWORD:', process.env.EMAIL_PASSWORD); // Create a Nodemailer transporter using SMTP with mail.com const transporter = nodemailer.createTransport({ host: 'smtp.mail.com', port: 587, // Use 587 for STARTTLS secure: false, // Use false for STARTTLS auth: { user: process.env.EMAIL_USERNAME, pass: process.env.EMAIL_PASSWORD, }, tls: { rejectUnauthorized: false, // Allow self-signed certificates if necessary }, }); export const requestPasswordReset = async (req, res) => { const { email } = req.body; try { const user = await User.findOne({ email }); if (!user) { return res.status(400).json({ message: 'Utilisateur non trouvé' }); } const resetToken = crypto.randomBytes(32).toString('hex'); const hashedToken = crypto.createHash('sha256').update(resetToken).digest('hex'); user.resetPasswordToken = hashedToken; user.resetPasswordExpires = Date.now() + 3600000; // 1 hour await user.save(); const resetUrl = `http://localhost:3000/reset/${resetToken}`; const mailOptions = { to: user.email, from: process.env.EMAIL_FROM, subject: 'Réinitialisation du mot de passe', text: `Vous recevez cet email parce que vous (ou quelqu'un d'autre) avez demandé la réinitialisation du mot de passe de votre compte.\n\n Cliquez sur le lien suivant ou copiez-le dans votre navigateur pour compléter le processus :\n\n ${resetUrl}\n\n Si vous n'avez pas demandé cette réinitialisation, veuillez ignorer cet email et votre mot de passe restera inchangé.\n`, }; await transporter.sendMail(mailOptions); res.status(200).json({ message: 'Email de réinitialisation envoyé' }); } catch (error) { console.error('Erreur lors de la demande de réinitialisation de mot de passe :', error); res.status(500).json({ message: 'Erreur lors de la demande de réinitialisation de mot de passe' }); } };
已尝试操作:
- 验证邮箱账号和密码正确;
- 确认.env文件加载正常,变量可访问;
- 测试
secure: true+端口465、secure: false+端口587等组合,均触发相同错误。
环境信息:
- Node.js版本:20.15.0
- Nodemailer版本:6.9.14
- 操作系统:Windows 11
错误原因
该错误核心是客户端与mail.com SMTP服务器的SSL/TLS版本协商不兼容。Windows环境下Node.js默认的SSL配置可能与mail.com服务器要求的版本不匹配,或者本地网络(防火墙、代理、SSL拦截工具)篡改了SSL握手数据包,导致服务器识别到错误的版本号。
解决方案
1. 强制指定兼容的TLS版本
在transporter的tls配置中明确指定支持的TLS版本范围,覆盖Node.js默认配置:
const transporter = nodemailer.createTransport({ host: 'smtp.mail.com', port: 587, secure: false, auth: { user: process.env.EMAIL_USERNAME, pass: process.env.EMAIL_PASSWORD, }, tls: { rejectUnauthorized: false, minVersion: 'TLSv1.2', maxVersion: 'TLSv1.3' }, });
2. 排查本地网络干扰
- 临时关闭Windows防火墙、杀毒软件的网络拦截功能,测试连接是否正常;
- 如果使用代理,暂时关闭代理后重试;
- 检查是否存在SSL拦截工具(如部分VPN、企业安全软件),这类工具会篡改SSL证书,导致握手失败。
3. 核对mail.com官方SMTP配置细节
mail.com官方SMTP要求:
- 端口587(STARTTLS):必须设置
secure: false,连接后自动升级TLS; - 端口465(SSL):必须设置
secure: true; - 确保
mailOptions.from的邮箱地址与auth.user完全一致,部分邮件服务器要求发件人必须为认证账号本身。
4. 更新依赖或测试Node.js版本
- 执行
npm update nodemailer更新到最新版本,修复可能存在的兼容性问题; - 若条件允许,测试Node.js 18.x版本,部分Windows环境下该版本的SSL配置兼容性更好。
内容的提问来源于stack exchange,提问作者Aqu1tain
相关产品推荐
相关产品推荐

