使用 Resend + Golang 发送邮件的完整踩坑与解决方案
使用 Resend + Golang 发送邮件的完整踩坑与解决方案
在实际开发中,我尝试使用 Resend 的 SMTP 服务结合 Golang 发送邮件(用于重置密码等场景),过程中踩了多个典型坑。本文从 错误现象 → 原因分析 → 最终正确方案 进行完整总结。
一、背景
目标:
- 使用 Golang 发送 HTML 邮件
- 接入 Resend SMTP
- 支持自定义域名发信(提升送达率)
二、Resend SMTP 基本认知(关键)
Resend 的 SMTP 和传统 SMTP 有一个重要区别:
| 类型 | 含义 | 示例 |
|---|---|---|
| SMTP Username | 登录用户名 | resend(固定) |
| SMTP Password | API Key | re_xxx |
| From(发件人) | 邮件发送地址 | noreply@xxx.com |
👉 重点:Username ≠ From
三、踩坑记录(按时间顺序)
❌ 问题 1:501 Bad sender address syntax
1 | 501 Error: Bad sender address syntax |
原因
1 | auth := smtp.PlainAuth("", m.from, m.password, m.host) |
把 from=resend 当成邮箱使用。
本质问题
resend不是合法邮箱地址- SMTP 要求符合 RFC 规范
❌ 问题 2:535 Invalid username
1 | 535 Invalid username |
原因
1 | auth := smtp.PlainAuth("", from, m.password, m.host) |
把邮箱当成 SMTP username。
正确规则
1 | username 必须是:resend |
❌ 问题 3:550 Missing or invalid “from” field
1 | 550 Missing or invalid "from" field: undefined |
原因
手写 SMTP message 时,没有加 Header:
1 | From: xxx |
关键点
SMTP 有两个 from:
| 类型 | 说明 |
|---|---|
| envelope from | SMTP 参数 |
| header from | 邮件内容 |
👉 两者必须同时存在
❌ 问题 4:550 domain is not verified
1 | The damingerdai.com domain is not verified |
原因
使用了:
1 | notifications@damingerdai.com |
但实际验证的是:
1 | notifications.damingerdai.com |
👉 域名不匹配
四、关键认知(最重要)
1️⃣ Resend 只认“已验证域”
假设你验证了:
1 | notifications.damingerdai.com |
那么合法发件人只能是:
1 | anything@notifications.damingerdai.com ✅ |
而不是:
1 | anything@damingerdai.com ❌ |
2️⃣ local-part 是自由的
1 | noreply@notifications.damingerdai.com |
👉 前缀不需要真实邮箱存在
五、最终正确配置
环境变量
1 | SMTP_HOST=smtp.resend.com |
六、Golang 实现
方案一:使用 net/smtp(低层)
1 | auth := smtp.PlainAuth("", m.username, m.password, m.host) |
方案二:使用 go-mail(推荐)
1 | msg := mail.NewMessage() |
七、最佳实践
✅ 使用子域发信(强烈推荐)
1 | notifications.damingerdai.com |
优势:
- 不影响主域信誉
- 更专业(邮件服务隔离)
✅ 设置规范发件人
1 | noreply@notifications.damingerdai.com |
✅ Header 使用带名称格式
1 | Health Master <noreply@notifications.damingerdai.com> |
八、总结
整个过程可以总结为三点:
1️⃣ 三个字段必须分清
1 | SMTP_USERNAME = resend |
2️⃣ 域名必须完全匹配
1 | 验证的是 A,就不能用 B |
3️⃣ SMTP 是“严格协议”
不会容错:
- 少一个 Header ❌
- 格式不对 ❌
- 域名不对 ❌
九、建议
如果不是必须用 SMTP:
👉 优先考虑 Resend API(更简单、更少坑)
十、附录(调试建议)
常见排查:
1 | dig TXT yourdomain.com |
检查:
- SPF
- DKIM
结尾
这次接入的核心教训:
SMTP 的问题,80% 不是代码问题,而是协议和配置问题。
如果你也在用 Golang + 邮件服务,这一套坑基本可以帮你全部避开。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Damingerdai's Blog!
