RFC 3464: 投递状态通知格式
ELI5: 当包裹无法送达时,快递员会给你一份表格,说明发生了什么。RFC 3464 定义了邮件服务器在邮件退回、延迟或成功送达时填写的标准化表格——结构化设计使软件可以自动读取。
为什么存在这个标准
在DSN格式标准化之前,每台邮件服务器都用自己的自由文本格式生成退信。解析这些"退信"需要使用脆弱的启发式方法——当服务器改变措辞时会中断的正则表达式。RFC 3464定义了一种机器可读的MIME内容类型(message/delivery-status),使自动退信处理更加可靠。
此RFC与RFC 3461(定义在SMTP级别如何请求DSN)和RFC 3462(定义包装DSN的multipart/report容器)配合使用。
工作原理
DSN消息是带有report-type=delivery-status的multipart/report MIME消息。它包含最多三个MIME部分:
-
人类可读的说明(
text/plain)——为人类设计的自由文本。 -
机器可读的状态(
message/delivery-status)——此RFC定义的结构化数据。 -
原始消息(
message/rfc822或text/rfc822-headers)——完整原始消息或仅其标题,取决于RFC 3461中的RET参数。
delivery-status正文
message/delivery-status部分包含由空行分隔的类似标题的字段组:
; 每个消息的字段(一个组) Reporting-MTA: dns; mail.example.org Original-Envelope-Id: msg-20260311-0042 Arrival-Date: Wed, 11 Mar 2026 10:30:00 -0500 ; 每个收件人的字段(每个收件人一个组) Original-Recipient: rfc822;bob@example.org Final-Recipient: rfc822;bob@example.org Action: failed Status: 5.1.1 Diagnostic-Code: smtp; 550 5.1.1 User unknown Last-Attempt-Date: Wed, 11 Mar 2026 10:30:05 -0500
主要技术细节
每个消息的字段
| 字段 | 必需 | 说明 |
|---|---|---|
Reporting-MTA |
是 | 生成此DSN的MTA,作为DNS主机名 |
Original-Envelope-Id |
否 | 来自原始SMTP事务的ENVID(RFC 3461) |
DSN-Gateway |
否 | 当DSN从外部邮件系统翻译而来时出现 |
Received-From-MTA |
否 | 将消息交给Reporting-MTA的MTA |
Arrival-Date |
否 | 原始消息到达Reporting-MTA的时间 |
每个收件人的字段
| 字段 | 必需 | 说明 |
|---|---|---|
Final-Recipient |
是 | MTA实际尝试投递的收件人地址 |
Original-Recipient |
否 | SMTP会话中的ORCPT值——发件人使用的地址 |
Action |
是 | 以下之一:failed、delayed、delivered、relayed、expanded
|
Status |
是 | 根据RFC 3463的增强状态代码(例如5.1.1) |
Diagnostic-Code |
否 | 来自远程服务器的实际错误字符串,前缀为类型(通常为smtp) |
Remote-MTA |
否 | 返回错误的MTA |
Last-Attempt-Date |
否 | 最后一次投递尝试的时间 |
Will-Retry-Until |
否 | 对于delayed操作,MTA将放弃的时间 |
操作值
| 操作 | 含义 |
|---|---|
failed |
永久失败——消息将不被投递(硬退信) |
delayed |
临时失败——仍在重试(软退信) |
delivered |
成功投递到收件人的邮箱 |
relayed |
转发到可能不会生成进一步DSN的环境 |
expanded |
投递到邮件列表或别名,其扩展为多个收件人 |
完整DSN消息示例
From: mailer-daemon@mail.example.org To: alice@sender.example.com Subject: Delivery Status Notification (Failure) MIME-Version: 1.0 Content-Type: multipart/report; report-type=delivery-status; boundary="DSN-BOUNDARY-001" --DSN-BOUNDARY-001 Content-Type: text/plain Your message to bob@example.org could not be delivered. The recipient's mailbox does not exist. --DSN-BOUNDARY-001 Content-Type: message/delivery-status Reporting-MTA: dns; mail.example.org Original-Envelope-Id: msg-20260311-0042 Arrival-Date: Wed, 11 Mar 2026 10:30:00 -0500 Final-Recipient: rfc822;bob@example.org Action: failed Status: 5.1.1 Diagnostic-Code: smtp; 550 5.1.1 User unknown --DSN-BOUNDARY-001 Content-Type: text/rfc822-headers From: alice@sender.example.com To: bob@example.org Subject: Meeting tomorrow Message-ID: <abc123@sender.example.com> --DSN-BOUNDARY-001--
常见错误
-
仅解析人类可读部分。
text/plain部分供人类使用。自动化系统应该解析message/delivery-status部分,该部分具有稳定的定义结构。 -
忽略状态代码等级。首位数字很关键:
2.x.x=成功,4.x.x=临时失败(稍后重试),5.x.x=永久失败(停止尝试)。将所有退信一视同仁会损害您的声誉。 -
不匹配Original-Envelope-Id。如果您在RFC 3461中设置了
ENVID,请使用Original-Envelope-Id将DSN关联回特定的发送。仅依赖Final-Recipient在涉及别名或转发时会失败。 -
混淆Final-Recipient与Original-Recipient。转发后,
Final-Recipient可能是完全不同的地址。如可用,始终检查Original-Recipient。 -
将
relayed视为delivered。relayed操作意味着消息离开了支持DSN的环境。您可能永远无法获得最终状态。
可投递性影响
-
自动退信分类。
Status字段映射到RFC 3463增强状态代码。代码5.1.1(用户不存在)意味着删除该地址;4.2.2(邮箱已满)意味着稍后重试。正确的分类是列表卫生的基础。 -
反馈循环关联。
Original-Envelope-Id让您将退信关联到特定的活动、API调用或交易——这对于调试和分析至关重要。 -
硬退信与软退信处理。将
Action: failed与5.x.x状态视为永久——抑制该地址。将Action: delayed与4.x.x视为瞬时——使用退避重试,但在重复失败后抑制。 - 声誉保护。及时处理DSN并删除无效地址可防止您重复命中死邮箱,邮箱提供商将此跟踪为负面声誉信号。