You set up SPF, you checked it twice, and every test says spf=pass. Then a DMARC aggregate report lands in your inbox, or a recipient forwards you a bounce, and it says dmarc=fail. It feels like a contradiction. How can the underlying check pass while the policy built on top of it fails?
It isn't a bug, and it usually isn't a DNS typo either. The missing piece is called identifier alignment. Once you understand which domain each check actually looks at, this error stops being mysterious and becomes a fairly mechanical fix. This guide walks through the concept, shows you how to read the headers that prove what's going on, and covers the fixes that work with real email service providers (ESPs).
The short version: SPF passing is not enough
DMARC, defined in RFC 7489, does not simply ask "did SPF pass?" or "did DKIM pass?" It asks a stricter question: did SPF or DKIM pass for a domain that matches the domain in the visible From: header? A message passes DMARC when at least one of those two mechanisms produces a pass result and the domain it authenticated is aligned with the From domain.
So there are two conditions, and SPF can satisfy the first while failing the second. That combination is exactly what produces "SPF pass, DMARC fail."
Why SPF checks a different domain than you think
Every email carries two different "from" addresses, and most people only ever see one of them:
- The envelope sender (RFC5321.MailFrom). This is the address given in the SMTP
MAIL FROMcommand. It's where bounces go, and receivers record it in theReturn-Pathheader. This is the domain SPF checks. - The header From (RFC5322.From). This is the
From:line your recipient sees in their mail client. This is the domain DMARC protects.
When you send through your own server, those two are often the same domain, so nobody notices the difference. When you send through an ESP such as a newsletter platform or a transactional email API, the provider frequently uses its own bounce domain for the envelope sender so it can process bounces for you. SPF then checks the provider's domain, the provider's SPF record authorizes its own servers, and SPF passes. But the domain that passed has nothing to do with example.com in your From line, so for DMARC purposes that pass doesn't count.
DKIM has the same trap. Many providers sign outgoing mail with their own domain by default, so the signature header contains d=esp.com. The signature verifies, DKIM passes, but esp.com isn't aligned with example.com, so DMARC can't use that result either.
What it looks like in the headers
Here is a simplified set of headers from a message sent through a provider with default settings:
Return-Path: <bounce-8f3a2c@bounces.esp.com>
From: Example Store <news@example.com>
DKIM-Signature: v=1; a=rsa-sha256; d=esp.com; s=s1; ...
Authentication-Results: mx.receiver.net;
spf=pass (sender IP is 203.0.113.10) smtp.mailfrom=bounces.esp.com;
dkim=pass header.d=esp.com;
dmarc=fail (p=QUARANTINE) header.from=example.com
Read it line by line:
spf=pass smtp.mailfrom=bounces.esp.commeans SPF passed, but forbounces.esp.com.dkim=pass header.d=esp.commeans DKIM passed, but foresp.com.dmarc=fail header.from=example.commeans DMARC evaluated the policy forexample.comand found no passing result that belongs to that domain.
Two passes, zero aligned passes, one DMARC failure. The headers tell the whole story once you know to compare the domain after smtp.mailfrom= and header.d= against the domain after header.from=.
How to check this yourself in Gmail
You don't need special tools to diagnose this. Send a test message to a Gmail address and then:
- Open the message, click the three-dot menu next to the reply button, and choose Show original.
- At the top, Gmail shows a summary table with SPF, DKIM, and DMARC results. Next to SPF it shows the domain it checked, and next to DKIM it shows the signing domain.
- Scroll down to the raw headers and find the
Authentication-Resultsheader added by Google. Look atsmtp.mailfrom=,header.d=(orheader.i=), andheader.from=. - Find the
Return-Pathheader and theDKIM-Signatureheader. Thed=tag in the signature is the signing domain.
Other mail clients have equivalents, usually called "View source," "View message source," or "Show headers." The header names are standardized, so the reading process is the same everywhere. If more than one Authentication-Results header appears, trust the one added by the final receiving server, typically the topmost.
Before you change anything, it also helps to confirm your DNS side is clean. Run your domain through the DMARC checker to see your current policy and alignment tags, the SPF checker to validate your SPF record, and the DKIM checker to confirm a selector's public key is published.
Relaxed vs. strict alignment
"Aligned" doesn't always mean "identical." DMARC has two alignment modes, controlled by two tags in your DMARC record:
aspfcontrols SPF alignment.adkimcontrols DKIM alignment.
Each tag takes r (relaxed) or s (strict), and both default to relaxed when you leave them out.
In relaxed mode, the two domains only need to share the same organizational domain, which is the registered domain such as example.com (or example.co.uk, since public suffixes are taken into account). So bounces.example.com aligns with example.com, and a DKIM signature with d=example.com aligns with a From address at news.example.com.
In strict mode, the domains must match exactly. bounces.example.com would not align with example.com.
v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; adkim=r; aspf=r
One thing relaxed mode will not do is bridge two different organizations. esp.com and example.com are different organizational domains, so no alignment mode makes them match. If your problem is a provider's domain in the headers, switching to relaxed won't help. It only helps when your setup is already using your own subdomains and you had strict mode turned on.
Fix 1: Set a custom Return-Path (bounce domain) at your ESP
This is the fix for SPF alignment. Most major providers let you use a subdomain of your own domain as the envelope sender. The feature goes by different names, such as "custom Return-Path," "custom MAIL FROM domain," "custom bounce domain," or "domain authentication," but the mechanics are similar:
- In the provider's dashboard, add a subdomain like
bounce.example.com. - Create the DNS record they give you, usually a CNAME pointing
bounce.example.comto a hostname on their side. Some providers ask for an MX record and an SPF TXT record on the subdomain instead. - Wait for verification, then confirm new messages show
smtp.mailfrom=bounce.example.com.
With relaxed SPF alignment, bounce.example.com now aligns with example.com. The provider still handles bounces, because the CNAME points the subdomain at their infrastructure.
Fix 2: Sign DKIM with your own domain
This is arguably the more important fix, because DKIM alignment survives situations where SPF breaks (more on forwarding below). Ask your provider for custom DKIM, often listed under "domain authentication" or "sender authentication." You'll typically publish one or more CNAME or TXT records at a selector, for example s1._domainkey.example.com. After that, the provider signs with d=example.com and your headers should show dkim=pass header.d=example.com.
Since DMARC needs only one aligned pass, getting DKIM aligned is often enough on its own. Having both aligned gives you redundancy.
Fix 3: Plan your subdomains deliberately
Many teams send marketing mail from news.example.com and transactional mail from mail.example.com to keep reputations separate. That works well with DMARC as long as you remember a few rules:
- With relaxed alignment, a DKIM signature for
example.comor a bounce domain underexample.comaligns with any From address underexample.com. - If you use strict alignment, each sending stream must authenticate the exact From subdomain it uses.
- Subdomains inherit the parent domain's DMARC policy unless the parent record sets
sp=or the subdomain publishes its own_dmarcrecord.
The forwarding and mailing list caveat
Even with a perfect setup, some legitimate mail will still fail. When a message is forwarded, the forwarding server relays it from its own IP address. Your SPF record doesn't authorize that IP, so SPF fails, or if the forwarder rewrites the envelope sender, SPF passes for the forwarder's domain, which isn't aligned with yours.
DKIM usually survives plain forwarding because the signature travels with the message and doesn't depend on the sending IP. It breaks when something modifies the signed parts of the message, which is what mailing lists commonly do by adding a subject tag or a footer. That's another reason to prioritize aligned DKIM.
Some intermediaries add ARC (Authenticated Received Chain) headers, which record the authentication results they saw before modifying the message. A receiver may take ARC into account when deciding how to handle a DMARC failure, but that's up to the receiver. ARC isn't something you configure in your own DMARC record, and it doesn't guarantee delivery.
Quick checklist
- Find
smtp.mailfrom=,header.d=, andheader.from=in a real message'sAuthentication-Results. - If
smtp.mailfromis your provider's domain, set up a custom Return-Path or bounce domain on your own subdomain. - If
header.dis your provider's domain, enable custom DKIM so mail is signed withd=yourdomain. - Keep
aspfandadkimrelaxed unless you have a specific reason for strict. - Check every service that sends as your domain, including CRM, helpdesk, billing, and forms.
- Review DMARC aggregate reports at
p=nonebefore moving toquarantineorreject.
FAQ
Do I need both SPF and DKIM to be aligned for DMARC to pass?
No. DMARC passes if either SPF or DKIM passes with an aligned domain. Aligning both is still recommended, because SPF tends to break when mail is forwarded and DKIM can break when a message is modified in transit.
Will changing aspf to relaxed fix a failure caused by my email provider?
Only if the authenticated domain is already a subdomain of your own domain. If the headers show the provider's domain, such as bounces.esp.com, no alignment mode will make it match example.com. You need a custom Return-Path or custom DKIM instead.
Why does SPF pass in my test tool but DMARC fails in Gmail?
Most SPF tools check your domain's record directly. Gmail checks the domain actually used in the envelope sender of that specific message, which may belong to your provider. Compare smtp.mailfrom= in the real headers with your From domain.
Is a DMARC failure on forwarded mail something I can fix?
Not completely, because the forwarder controls how the message is relayed. Aligned DKIM gives you the best chance, since it typically survives forwarding when the message isn't changed. Some forwarders and lists also add ARC headers, which receivers may consider.
Where do I see which domain DKIM used?
Look at the d= tag in the DKIM-Signature header, or at header.d= in Authentication-Results. In Gmail's "Show original" summary, the DKIM row also shows the signing domain.