You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Nodemailer发邮件遇ECONNRESET错误求助(本地正常服务器失败)

服务器环境下使用Nodemailer连接SMTP服务出现ECONNRESET错误

问题背景

使用smtp.emailcloud.smartping.io作为SMTP服务提供商,本地环境可正常发送邮件,但部署到服务器后出现连接重置错误。

错误信息

SendMail error: ==>> Error: read ECONNRESET
at TLSWrap.onStreamRead (node:internal/stream_base_commons:217:20) {
   errno: -104,
   code: 'ESOCKET',
   syscall: 'read',
   command: 'CONN'
}

原始代码

const transporter = nodemailer.createTransport({
    host: process.env.SMTP_HOST,
    port: process.env.SMTP_PORT,
    secure: false,
    auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS
    },
    tls: {
        rejectUnauthorized: false
    },
    dnsTimeout: 180000, //3 minutes timeout
    debug: true,
    logger: true,
})

const sendEmail = async (emailData) => {
    try {
        const { senderEmail, sendTo, subject, emailBody, attachmentName } = emailData;

        const attachmentPath = path.join(process.cwd(), 'uploads/attachments', attachmentName);

        const mailOptions = {
            from: senderEmail,
            to: sendTo,
            subject: subject,
            html: emailBody,
            attachments: attachmentName !== 'null'
                ? [
                    {
                        filename: attachmentName,
                        path: attachmentPath
                    }
                ]
                : []
        }
        if (emailData.cc) {
            mailOptions['cc'] = emailData.cc;
        }
        console.log('mailOptions', mailOptions);
        transporter.sendMail(mailOptions)
            .then(info => console.log('Email sent: ==>>', info))
            .catch(error => console.error('SendMail error: ==>>', error));
    } catch (error) {
        console.log('error -->>', error);
        Sentry.captureMessage("Something went wrong in sendEmail util function");
        Sentry.captureException(error);
    }
};

已尝试的配置修改

const transporter = nodemailer.createTransport({
    host: process.env.SMTP_HOST,
    port: 465,
    secure: true,
    auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS
    },
    tls: {
        rejectUnauthorized: false
    },
    dnsTimeout: 180000, //3 minutes timeout
    debug: true,
    logger: true,
})

排查与解决方案建议

  • 服务器网络限制检查

    • 确认服务器安全组/防火墙是否放行SMTP端口(25/465/587),多数云服务商默认封禁25端口,优先检查465或587端口的出站权限。
    • 联系服务器提供商确认是否存在邮件发送拦截策略,部分服务商对非官方SMTP服务有流量限制。
  • SMTP服务端IP白名单验证

    • 登录smartping.io后台,检查是否设置了IP白名单规则,将服务器公网IP添加到允许列表中(本地能发送大概率是因为本地IP已在白名单内)。
  • TLS兼容性调整

    • 服务器环境的TLS版本可能与SMTP服务端不兼容,尝试指定TLS最低版本:
      tls: {
          rejectUnauthorized: false,
          minVersion: 'TLSv1.2'
      }
      
    • 确保secure选项与端口匹配:465端口对应secure: true,587端口对应secure: false(依赖STARTTLS升级连接),避免配置冲突。
  • 服务器网络连通性测试

    • 在服务器终端执行telnet smtp.emailcloud.smartping.io 465或telnet smtp.emailcloud.smartping.io 587,验证是否能建立TCP连接,无法连接则定位为网络问题。
    • 执行nslookup smtp.emailcloud.smartping.io确认服务器能正确解析SMTP域名,排除DNS解析失败导致的连接异常。
  • Nodemailer版本与代码优化

    • 检查服务器端Nodemailer版本是否与本地一致,执行npm update nodemailer升级到最新稳定版,避免旧版本兼容性问题。
    • 优化异步处理逻辑,将then/catch改为await方式,便于捕获完整错误信息:
      try {
          // ... 其他代码
          const info = await transporter.sendMail(mailOptions);
          console.log('Email sent: ==>>', info);
      } catch (error) {
          console.error('SendMail error: ==>>', error);
          Sentry.captureMessage("Something went wrong in sendEmail util function");
          Sentry.captureException(error);
      }
      

内容的提问来源于stack exchange,提问作者Art Light

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:27:40