为什么退信是异步的
SMTP 的投递是逐跳转发:本跳在 DATA 之后返回 250 只代表「已接收并进入队列」,真正的接收方可能几分钟到几天后才处理。若最终投递失败,邮件系统会生成退信(Bounce)投回信封发件人地址,这个动作由 DSN(投递状态通知,RFC 3464)描述,其中的增强状态码说明失败原因。
基本信息
| 退信收件人 | 信封发件人(MAIL FROM),不是正文 From 头 |
|---|---|
| 增强码结构 | class.subject.detail 三段,首段 2 为成功、4 为临时失败、5 为永久失败 |
| 常见触发 | 收件人不存在、邮箱满、被策略拒收、投递超时 |
| 队列超时 | 多数实现约 4 到 5 天后放弃并退信,期间会持续重试 |
失败反馈的时机
| 阶段 | 失败反馈形式 | 时机 |
|---|---|---|
| 连接或命令阶段 | 同步 4xx / 5xx 拒收 | 当场可见,可立即处理 |
| DATA 之后 | 250 排队确认,不等于已投递 | 异步 |
| 投递失败 | 退信退回信封发件人 | 数分钟到数天 |
| 长期失败 | 队列超时后放弃并退信 | 通常 5 天左右 |
退信关键字段
退信关键字段
Action: failed
Status: 5.1.1
Diagnostic-Code: smtp; 550 5.1.1 <b@example.net>: Recipient address rejected: User unknown
# Action 也可为 delayed(仍在重试)或 delivered(成功)
# Original-Recipient 段标明真正失败的收件人典型使用场景
- 用户投诉「没收到邮件」:先查退信日志,比反复重发更快定位
- 邮件系统做地址清洗:用 5.1.1 永久失败标记无效地址,避免长期空投
- 区分临时与永久失败:4.x.x 应继续重试,5.x.x 说明重试无用
- 排查「对方把我拉黑了」:5.7.1 类策略拒收通常附带申诉链接
常见增强码
| 增强码 | 含义 | 处理建议 |
|---|---|---|
| 5.1.1 | 收件人不存在 | 标记无效地址,停止重试 |
| 5.2.2 | 邮箱空间已满 | 通知收件人清理后重发 |
| 5.4.7 | 投递超时 | 检查对端 MX 可达性 |
| 5.7.1 | 被策略拒收 | 查黑名单与 SPF/DKIM/DMARC 配置 |
| 4.4.1 | 对端连接超时 | 多为临时故障,保留重试 |
发信程序应把「已提交」与「已投递」当成两件事:接口返回成功只代表入队,若业务需要确认,应使用 VERP 或专门的投递状态回调,而不是靠轮询收件箱。
批量外发时把退信率压下去才有送达率:对 5.1.1 地址持续重发会拉低发信域的信誉,最终导致正常邮件被大规模判定为垃圾邮件。