"But SPF passes! DKIM passes! How can DMARC be failing?" is the most common confused message we get about authentication. The answer is always alignment. SPF and DKIM can each pass perfectly well while authenticating a domain that isn't the one the user sees — and DMARC cares about the one the user sees. Once you understand that, the fix is straightforward.
For DMARC to pass, at least one of SPF or DKIM must not only authenticate, but authenticate the same domain the recipient sees in the From header. If SPF authenticates bounces.esp.com and DKIM signs with d=esp.com but the From is you@brand.com, DMARC fails. Fix: configure custom Return-Path and custom DKIM at your ESP so both authenticate brand.com.
What alignment means
A mail message carries three different "from" domains that most people don't realise are different:
- The From header —
From: you@brand.com. This is what the recipient's mail client displays. - The Return-Path / envelope sender — the SMTP
MAIL FROMused during delivery. SPF authenticates this domain. - The DKIM
d=domain — the signing domain named in the DKIM-Signature header.
DMARC alignment is the requirement that at least one of the latter two matches the first. If From says brand.com and nothing else says brand.com, DMARC fails — no matter how solid the underlying SPF and DKIM checks are.
SPF alignment
SPF's job is to authenticate the envelope sender (MAIL FROM). SPF passes. Alignment asks the separate question: does that envelope domain match the From domain?
Two alignment modes:
- Relaxed (
aspf=r, default): subdomains are OK. Return-Pathbounces.brand.comaligns with Frombrand.com. - Strict (
aspf=s): exact match required. Return-Path must be literallybrand.com.
Classic breakage: your ESP uses MAIL FROM: bounce-42@mail.esp.com by default. SPF passes for esp.com. But the From is you@brand.com. esp.com isn't a subdomain of brand.com, so SPF alignment fails.
DKIM alignment
DKIM alignment compares the d= tag of the DKIM signature with the From domain.
- Relaxed (
adkim=r, default): shared organisational domain is OK.d=mail.brand.comaligns with Frombrand.com. - Strict (
adkim=s): exact match.d=brand.comrequired.
Classic breakage: ESP signs with its own domain. The DKIM-Signature header on your outbound mail says d=mailgun.org, the From is you@brand.com. Signature is valid and mailgun.org publishes the public key. DKIM check passes. Alignment fails.
Why relaxed alignment is usually right
Strict alignment sounds safer but breaks normal operations. Most real sending setups use a subdomain for bounces — it's cleaner reputation-wise, and it lets you isolate failures. Under strict alignment, bounces.brand.com doesn't align with brand.com, so you'd have to fold every subdomain bounce flow into the apex or fail.
Default to aspf=r; adkim=r. Consider switching to strict only after months of clean aggregate reports and as part of a hardening exercise alongside publishing BIMI or signing with VMCs — places where exact-match is meaningful. For the vast majority of senders, relaxed is correct forever.
Why ESPs break alignment by default
Every ESP — SendGrid, Mailgun, Postmark, Mailchimp, SparkPost — defaults to using their domain for Return-Path and DKIM d=. They do this because it's easier for their infrastructure to manage bounce handling centrally and because signing with their domain guarantees a valid signature even if the customer hasn't configured DNS yet.
The downside is that out of the box, DMARC-protected senders fail alignment. Every modern ESP offers a configuration option — sometimes called "custom sending domain," "domain authentication," or "branded sending" — that lets you move both envelope and DKIM to your own domain.
Fix for SPF alignment
The SPF alignment fix is a custom bounce domain (sometimes called custom MAIL FROM or custom Return-Path). Steps:
- In your ESP, pick a subdomain for bounces. Common choices:
bounce.brand.com,em.brand.com,mail.brand.com. - The ESP gives you DNS records — typically an MX and a TXT (SPF) for that subdomain, plus sometimes a CNAME.
- Publish the records exactly as provided. The SPF record for the subdomain will include the ESP's SPF infrastructure.
- Click "verify" in the ESP. Send a test; confirm that the received message's Return-Path header ends in your subdomain, not the ESP's.
After this, SPF authenticates bounce.brand.com, which aligns with From: you@brand.com under relaxed mode.
Fix for DKIM alignment
The DKIM alignment fix is signing with your domain, not the ESP's. Every serious ESP supports this — usually by generating a CNAME that points to a record they host:
s1._domainkey.brand.com CNAME s1.domainkey.u123456.wl.sendgrid.net
s2._domainkey.brand.com CNAME s2.domainkey.u123456.wl.sendgrid.netPublish the CNAMEs and the ESP starts signing outbound mail with d=brand.com. Verify by opening a received message and checking the DKIM-Signature header — d= should now match your sending domain.
Reading alignment in aggregate reports
DMARC aggregate reports include explicit alignment flags per row. Look for entries like:
source_ip: 149.72.142.198
count: 1543
header_from: brand.com
auth_results:
spf: pass domain=esp.com result=pass
dkim: pass domain=esp.com selector=s1 result=pass
policy_evaluated:
disposition: none (because p=none)
spf: fail <- SPF pass but NOT aligned with header_from
dkim: fail <- DKIM pass but NOT aligned with header_fromThis is the exact pattern that causes the "SPF passes, DKIM passes, DMARC fails" confusion. Both mechanisms authenticate esp.com. Neither aligns with the header_from: brand.com. DMARC fails. Once you publish custom Return-Path and custom DKIM, the same report rows become:
auth_results:
spf: pass domain=bounce.brand.com result=pass
dkim: pass domain=brand.com selector=s1 result=pass
policy_evaluated:
disposition: none
spf: pass <- aligned
dkim: pass <- alignedTightening once confident
If you control every sender perfectly and want maximum protection against exact-domain spoofing, consider aspf=s; adkim=s. This blocks attackers from spoofing brand.com using any subdomain trick — an edge case but a real one.
Don't tighten without first running at least a month on relaxed with clean aggregate reports. The transition will break anything using a subdomain for bounces, and catching that pre-rollout is much cheaper than fighting it post-rollout.
If the From header says you@brand.com, then at least one of the Return-Path or the DKIM d= must also say brand.com (or a subdomain of it). If neither does, DMARC fails — no matter how clean the underlying SPF and DKIM checks are.