Authentication vs. alignment
SPF and DKIM each authenticate a domain. SPF authenticates the domain in the
RFC5321.MailFrom — the envelope sender, also called the bounce address or
Return-Path. DKIM authenticates whatever domain signed the message, taken
from the signature’s d= tag. Neither one, by itself, says anything about
who the message claims to be from in the header a mail client displays.
DMARC adds exactly one new check on top of both: alignment. It compares
the domain that SPF or DKIM just authenticated against the domain in
RFC5322.From — the visible From header. A message passes DMARC if at
least one of SPF or DKIM passes and is aligned. All four combinations of
authentication and alignment are possible, and “SPF passed, DKIM passed,
DMARC failed” is one of the most common support tickets in any DMARC
rollout.
Alignment comes in two modes, set independently for SPF (aspf) and DKIM
(adkim):
- Relaxed (the default): the authenticated domain and the From domain
must share an organizational domain.
mail.example.comaligns withexample.com. - Strict: the domains must match exactly.
mail.example.comdoes not align withexample.comunder strict mode.
A worked example
Say example.com uses a marketing ESP to send a newsletter. A typical set
of headers on the delivered message looks like this:
Return-Path: <[email protected]>
Received-SPF: pass (espvendor.net: domain of [email protected] designates 198.51.100.42 as permitted sender)
DKIM-Signature: v=1; a=rsa-sha256; d=espvendor.net; s=selector1; ...
From: "Example Co. Newsletter" <[email protected]>
To: [email protected]
Subject: This week at Example Co.
Walking through it:
- SPF: the envelope sender is
[email protected]. SPF authenticatesespvendor.net. It passes — againstespvendor.net. - DKIM: the signature’s
d=tag isespvendor.net. It validates. It passes — again, againstespvendor.net. - Alignment: the From header is
[email protected]. Neitherespvendor.netresult aligns withexample.com, under relaxed or strict mode. - DMARC verdict: fail. Both underlying mechanisms passed; nothing aligned.
The receiving mailbox provider’s Authentication-Results header usually
spells this out directly:
Authentication-Results: mx.recipient.example;
spf=pass (domain of bounces.espvendor.net designates 198.51.100.42 as permitted sender) smtp.mailfrom=bounces.espvendor.net;
dkim=pass header.d=espvendor.net;
dmarc=fail (p=quarantine sp=quarantine dis=quarantine) header.from=example.com
dmarc=fail next to two pass results, with the policy disposition
(dis=quarantine) spelled out, is the signature of an alignment failure —
not a broken authentication setup.
The three culprits, in practice
ESPs with a shared or vendor-owned Return-Path. If the ESP sends on your behalf from its own bounce domain and signs with its own DKIM key (the example above), you need one of the alignment fixes covered in sending DMARC-compliant email on behalf of others — a custom Return-Path subdomain, a delegated DKIM selector, or both.
Forwarding. When a message is forwarded, SPF almost always breaks — the forwarding server isn’t in the original sender’s SPF record, so the envelope sender it now uses fails. DKIM, if the forwarder doesn’t modify the body or signed headers, can survive intact and pass, still aligned with the original From domain. This is why DKIM alignment matters even when SPF alignment is unreliable: a well-configured sender that relies on DKIM survives forwarding; a sender relying on SPF alone does not. See how DMARCLoop identifies sources, forwarding and threats for the signature this leaves in aggregate reports.
Third-party senders signing with their own domain. Some platforms sign
outgoing mail with d= set to their own sending domain rather than yours,
regardless of what Return-Path they use. If DKIM doesn’t align and SPF
doesn’t align either, the message fails DMARC even though the third party
did everything right by its own authentication.
Checking your own alignment
The Domain Checker runs SPF, DKIM, DMARC and MX
together and flags misaligned results against your domain’s DMARC policy.
For a single message, look at the Authentication-Results header the way
this article does: find the smtp.mailfrom and header.d domains, and
compare each to header.from.