DKIM 验证失败的三类原因,从选择器查起

云臻技术支持 更新于 2026-10-29 阅读约 11 分钟
直接回答

先看收件方返回的 dkim= 结果码。none 是记录没查到,多半是选择器名拼错,或者域名商后台自动补了主域名;fail(bad signature)是记录查到了但公钥对不上,通常是 TXT 值被截断或带进了空格;dkim=pass 而 dmarc=fail 是签名域与 From 域不对齐,去查 DKIM-Signature 里的 d=。三类错法对应三个检查位置。

先把分工说清。SPF、DKIM、DMARC 怎么配那篇讲的是从零配起来:密钥怎么生成、TXT 填什么、后台哪一步点验证。这篇不重复那些步骤,只管一件事——配完之后验证不过,问题出在哪。

这个处境比配之前更难。配置有文档可抄,排查没有。后台点一下「验证」,返回一个红叉或者一句「DKIM 验证失败」,不说是哪一层断的。于是大多数人会做同一件事:把 TXT 值删掉重贴一遍,再点一次。三次之后开始怀疑服务商。

其实断点只有三个位置:记录没查到、查到了但内容不对、内容对但域名对不上。三者的现象不一样,看一眼结果码就能分开。

先分清是哪一种失败

DKIM 的结果码出现在收件方返回的验证头里,不在你的后台。拿一封测试信发到 Gmail,打开「显示原始邮件」,找 Authentication-Results,里面 dkim= 后面那一段就是。

结果码谁的问题第一个该查的地方
dkim=none信里没有签名,或签名的选择器查不到后台是否已开启 DKIM;选择器名有没有抄错
dkim=fail(bad signature)记录查到了,但公钥对不上签名这条选择器的公钥是不是当前这一把
dkim=fail(body hash did not verify)签名之后正文被改过有没有在签名后追加页脚、统计代码、免责声明
dkim=temperror查询过程出错,不是配置问题DNS 超时或解析商抖动,等半小时再试
dkim=permerror记录格式不合法,解析不了TXT 值本身,尤其 p= 后面是不是空的
dkim=pass 但 dmarc=fail签名成立,但签名域与 From 域不对齐DKIM-Signature 里的 d=

最后一行是最容易误判的一行。后台显示「DKIM 验证通过」,你以为完事了,客户那边却仍然判 dmarc=fail,信照旧进垃圾箱。这跟公钥、跟记录长度都没关系,是签名签在了另一个域名上。第四节单独讲。

另外两个码要分开看:temperror 不用改任何东西,改也白改;permerror 一定是记录写坏了,回 DNS 后台。看到 none 别急着查 DNS——先确认签名到底有没有开。

还有一种情况表里没列:返回 dkim=none 但记录明明是有的。这时候看 From: 的域名和签名的域名是不是同一个域名的不同子域,两个子域各有各的 _domainkey,查错域等于没配。

原因一:选择器名和记录名,差一个字符就是两条记录

DKIM 的记录名是拼出来的:选择器._domainkey.你的域名。这里的「选择器」由邮件服务端生成,可能叫 dkim、s1、default,也可能是一串编号。它必须前后一致——后台写的什么,DNS 主机记录就得是什么。

第一个高频错误是域名商后台自动补全。多数域名商的「主机记录」框只填前缀,系统会自动接上你的主域名。这时候填 dkim._domainkey 是对的;但如果有人把完整域名 dkim._domainkey.example.com 整个粘进去,最终生成的记录名就变成 dkim._domainkey.example.com.example.com。这条记录语法完全合法,能保存成功,就是永远查不到。

第二个是选择器抄错。后台把选择器和公钥并列显示,两个字段都是长字符串,复制时容易串行。判别方法很简单:查出来的值里,v=DKIM1 应该在开头,p= 后面是 base64 公钥。如果查到的是一串看着像公钥的东西却没有 v=DKIM1,说明查到的是别的记录。

第三个是多了一个点。有些服务商给的选择器自带尾点,写进主机记录就变成 dkim.._domainkey。DNS 不报错,查询直接落空。

一条命令查清楚:

dig txt dkim._domainkey.你的域名.com

返回 NXDOMAIN 就是记录压根不存在,先把名字对齐,别去动公钥。返回了值、但被拆成好几段引号括起来的字符串,那是正常的——同一条 TXT 超过 255 字符必须分段,拼起来才是一条完整记录。分不清「分段」和「两条记录」的人,会把正确配置当成错误删掉。

原因二:公钥那一串,断在哪一位都不行

这一类的症状很典型:dig 能查到记录,格式看着也没问题,但收件方判 bad signature。原因就一句话——你贴进去的公钥,和后台生成的那一把不是同一个。

怎么被改坏的,四种走法:

  • 后台输入框截断。2048 位密钥的 TXT 值通常在 400 字符以上。部分域名商单条记录上限偏小,超了不报错,静默切掉尾巴。切掉的位置正好在 p= 的后半段。
  • 只粘了第一段。TXT 值被拆成多段引号字符串后,有人只复制了第一段。查询能显示,但公钥不完整。
  • 带进了换行或空格。从邮件、微信、Word 里复制时最常见。base64 里不允许出现空白字符,一个空格就够判失败。
  • 换行被转成了 \n 字面量。有些后台会把粘贴内容里的换行转义,屏幕上看着是断行,实际写进去的是两个字符。

核对的办法不是肉眼看,是字符串比对。把后台给的完整值去掉所有空白,和 dig 出来拼接后的值同样去掉空白,逐字比。长度一致、结尾一致,才算对上。长度不一致就是被截断了,换一条支持长 TXT 的记录方式,或者降到 1024 位密钥。

关于密钥长度有个取舍要说清:2048 位更安全,但一部分老邮件网关只认 1024 位,遇到这种网关往往判 permerror 而不是 fail,现象更难看。现在的收件方基本都支持 2048 位,新配的域名直接用 2048。已经在用 1024 位、又没出过问题的,不必为了「更安全」专门换——换密钥就要改 DNS,改 DNS 就有出错窗口。

还有一种 fail 跟公钥无关:body hash did not verify。签名只保头部和正文的哈希,正文在签名之后被改过就必失败。企业邮箱里最典型的场景是「统一追加免责声明」或者「营销邮件统一插页脚」——如果这个动作发生在签名环节之后,信就废了。这类问题改 DNS 一辈子也修不好,得去查邮件系统里那些后置处理规则。

原因三:签名域和 From 域不是同一个

这一类最费时间,因为所有体检项都是绿的:dkim=pass、spf=pass,但客户那边仍然进垃圾箱,报告里写 dmarc=fail。

根子在「对齐」。DMARC 判通过的条件不只是「SPF 或 DKIM 至少一个过」,而是通过的那一项,域名要和 From 头里的域名对得上。

举个具体的:公司主域名 example.com,官网表单的询盘通知由某个 SaaS 平台代发,平台用自己的域名签 DKIM(d=saas-platform.com),From 却显示 service@example.com。这时 dkim=pass 成立——签名确实有效;但签名域是 saas-platform.com,From 域是 example.com,两边对不上,DMARC 判失败。

这也解释了为什么「后台验证通过」和「实际投递正常」是两件事。后台验的是「记录填对了没有」,DMARC 验的是「这封信该不该由你这个域名发」。

对齐有两档,写在 DMARC 记录里:

参数宽松(r,默认)严格(s)
adkim签名域是 From 域的子域,也算对齐必须完全一致
aspf返回路径域是 From 域的子域,也算对齐必须完全一致

默认的宽松模式能覆盖「用 mail.example.com 签名、From 是 example.com」这类常见情况,所以多数公司不用改这一项。真正需要动的是发信源:让第三方平台用你的子域名发信,并给子域名单独配 DKIM。这样签名域变成 notice.example.com,宽松模式下与 example.com 对齐,DMARC 就能过。子域名要单独加一条 DKIM 记录,也要在平台侧单独配置,工作量不小,但比「主域名信誉被营销邮件拖着走」划算。

判断方法:打开原始邮件,找 DKIM-Signature 这一段,看 d= 后面是什么,再和 From: 后面的域名比。不一致就是这个问题,改公钥没有用。

改的顺序:DKIM 可以并存,SPF 不行

这一条跟 SPF 的排查逻辑正好相反,值得单独记。

SPF 一个域名只能有一条记录,出现两条直接判 permerror,比不配还糟。DKIM 不一样:不同选择器是不同的记录名,天然可以并存。你可以同时存在 dkim._domainkey、s1._domainkey、s2._domainkey 三条,各管各的签名,互不干扰。

这个差别决定了改法。换服务商、轮换密钥的时候,正确顺序是先加新的,验证通过,再删旧的——跟 SPF 完全相反。原因很实际:旧记录删早了,还在用旧密钥签名的历史邮件、还在跑的老系统,会立刻开始被判 none。

保留多久:至少留一个 TTL 周期,再加旧系统的发信周期。稳妥的做法是留 48 小时,确认没有系统还在用旧选择器签名,再删。

还有一个坑在迁移场景:域名解析切到新服务商了,DKIM 密钥换了,但 Outlook 里配的是旧账号、旧服务器。这时从客户端发出的信可能根本没有签名,或者带的是旧服务的签名。症状是「网页版正常、客户端发的被判 none」。遇到这种,先核对客户端的 SMTP 地址是不是新的,别一头扎进 DNS。

复核清单:改完只看三件事

  1. 记录名对不对。dig txt 选择器._domainkey.你的域名 有返回值,且值以 v=DKIM1 开头。
  2. 公钥全不全。去掉空白后逐字比对长度。结尾不能缺,中间不能有空格。
  3. 签名域对不对齐。原始邮件里 d= 与 From: 的域名一致,或者是它的子域。

三项都过,再发一封测试信看 dkim=pass 且 dmarc=pass。只看 dkim=pass 不够,原因上面说过——签名成立但域不对齐,一样算失败。

最后提醒一句时间账:改完 DNS 不要立刻判死刑。TXT 记录受 TTL 影响,生效要等缓存过期,逻辑跟 MX 记录多久生效是同一套。改完一分钟就查,查到的多半还是旧值,然后你会误判成「没生效、再改一遍」,把本来对的记录改坏。

DKIM 和 SPF 属于同一类问题:结果码只在收件方那边,你这边改十遍也不知道对不对。两者的错法也有重合,尤其是「记录被截断」和「并存」这两条最容易搞混。真要分清一封被拒的信死在哪一环,先看退信里的报错码,码表在 退信报错码对照。

相关问题

DKIM 验证失败但 SPF 是 pass,邮件还会进垃圾箱吗?

会。SPF 只证明发信 IP 在授权范围内,证明不了内容没被改。现在主流收件方看的是 DMARC,DMARC 要求 SPF 或 DKIM 至少一项通过、且与 From 域名对齐。SPF 过而 DKIM 挂,只要对齐成立 DMARC 仍可能通过;但如果 SPF 也没对齐,两项都白做,进垃圾箱不奇怪。

DKIM 记录里 p= 后面那串公钥太长,能只填一部分吗?

不能。公钥是一个完整字符串,少一位就验不过,判 bad signature。TXT 单条超过 255 字符会被拆成多段引号字符串,那是 DNS 的正常分段,粘进后台时要全部拼上,不能只取第一段。填完用 dig 查一遍,把返回的几段去掉引号和空白拼起来,长度必须和后台给的一致。

换了邮箱服务商,旧的 DKIM 记录要不要马上删?

不要马上删,这点和 SPF 相反。DKIM 不同选择器是不同记录名,可以并存,所以正确顺序是先加新记录、验证通过、再删旧的。旧记录删早了,还在用旧密钥签名的系统和历史邮件会立刻被判 none。稳妥留 48 小时,确认没有系统还在用旧选择器再删。

后台显示 DKIM 验证通过,为什么客户收到的信还是判 dmarc=fail?

因为签名域和 From 域不是同一个。比如第三方平台用自己的域名签名(d=saas-platform.com),From 却是你的域名,这时 dkim=pass 成立但域不对齐,DMARC 判失败。打开原始邮件看 DKIM-Signature 里的 d=,与 From: 的域名比一下就知道。解法是让平台用你的子域名发信并单独配 DKIM。

DKIM 密钥用 1024 位还是 2048 位?

新配的一律 2048 位。2048 位更安全,TXT 值也更长(400 字符以上),对域名商后台的记录长度上限要求更高,容易踩截断的坑,填完必须复核完整性。1024 位是给老网关留的退路,一些老设备只认这个长度。已经在用 1024 位且投递正常的,不必专程去换,换密钥就要动 DNS,反而制造出错窗口。

获取报价 电话咨询