Authentication-Results reports a DKIM outcome as one of seven values, and each corresponds to a different stage of verification failing. The value alone narrows the cause considerably.
The seven
| Result | Stage reached | What it means |
|---|---|---|
pass | Complete | Body hash matched, signature verified against a published key. |
fail | Verification | A key was found and the signature did not verify against it. Something changed, or the key is wrong. |
none | Nothing attempted | The message carried no DKIM-Signature at all. |
neutral | Parsing | A signature was present but malformed or unusable — a missing required tag, an unknown algorithm. |
temperror | Key retrieval | DNS failed transiently. Retry would likely succeed. Nothing is wrong with the message. |
permerror | Key retrieval | The key record is absent, syntactically invalid, or revoked. |
policy | Local policy | The signature verified and the receiver declined to honour it — usually a key below its size floor. |
RFC 8601 defines the vocabulary. Receivers vary in how precisely they use it — some report fail where permerror would be exact — so treat the value as a strong hint rather than a verdict.
Reading a real header
Authentication-Results: mx.receiver.example; dkim=pass header.d=example.com header.s=mail202609; spf=pass smtp.mailfrom=bounce.vendor.example; dmarc=fail header.from=example.com
Three results, and the interesting one is the combination. DKIM passed for example.com; SPF passed for a different domain; DMARC still failed. That can only mean the DKIM pass was not aligned in the receiver’s judgement, or — far more often — that this is the second of two signatures and the aligned one failed. The presence of header.d and header.s is what lets you tell.
Always read header.d, never just the result
dkim=pass on its own is nearly meaningless for DMARC purposes. A vendor signing as itself passes DKIM every time. The question is always which domain passed, and header.d is the answer.
Several signatures, several results
dkim=fail header.d=example.com header.s=old2025; dkim=pass header.d=gateway.example.net header.s=g1;
This is a real and common shape: the aligned signature failed, an unaligned one passed. DMARC sees no aligned pass and fails, while a casual glance at the header shows dkim=pass and suggests everything is fine. Reading only the first result, or only the last, is how this gets missed.