DMARC failing while SPF passes and DKIM passes? This looks like a contradiction and is not. DMARC does not simply ask "did authentication succeed" — it asks "did authentication succeed for the domain the recipient can see". That extra requirement is called identifier alignment, and it is the cause in almost every case.
The Error
Authentication-Results: mx.google.com;
dkim=pass header.i=@mail.sendingvendor.example header.s=s1;
spf=pass (google.com: domain of bounces@mail.sendingvendor.example
designates 198.51.100.25 as permitted sender)
smtp.mailfrom=bounces@mail.sendingvendor.example;
dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=example.com
Read the three domains carefully:
- DKIM passed for
mail.sendingvendor.example - SPF passed for
mail.sendingvendor.example - The visible From address is
example.com
Both checks succeeded. Neither succeeded for your domain. In DMARC aggregate reports the same condition appears as fail-unaligned, or as a record showing spf: pass and dkim: pass under a disposition of fail.
Why This Happens
RFC 7489 §3.1 explains the design:
DMARC authenticates use of the RFC5322.From domain by requiring that it match (be aligned with) an Authenticated Identifier.
The From: header is what users actually see, so it is what DMARC protects. But SPF and DKIM each authenticate a different identifier:
| Check | Authenticates | Where it comes from |
|---|---|---|
| SPF | The envelope sender (RFC5321.MailFrom) | The SMTP MAIL FROM command — invisible to the recipient |
| DKIM | The signing domain (d= tag) | The DKIM-Signature header |
| DMARC | The From: header (RFC5322.From) | What the user sees |
DMARC passes only if at least one of SPF or DKIM both passes and is aligned with the From domain. One aligned pass is enough. Two unaligned passes are worth nothing.
Relaxed vs strict alignment
RFC 7489 defines two modes, and relaxed is the default for both checks.
- Relaxed — the two domains need only share an Organizational Domain. RFC 7489 §3.1.1 gives the example: a DKIM
d=example.comaligns with a From address ofalerts@news.example.com. - Strict (
aspf=s,adkim=s) — the fully qualified domain names must match exactly. In strict mode that same example fails.
RFC 7489 §3.1.2 gives the SPF equivalent: an envelope sender of cbg.bounces.example.com with a From of payments@example.com is aligned in relaxed mode, but not in strict.
So there are only three ways to fail with both checks passing:
- The authenticated domains belong to a third-party vendor, not to you — by far the most common
- You have set strict alignment and are sending from a subdomain
- The vendor signs with your domain but uses their own bounce domain, and there is no DKIM to fall back on
Fix 1: Confirm It Is Really Alignment
Get the full headers of a failing message and compare the three domains. Our email header analyzer parses the block and lays out the SPF domain, the DKIM d= value and the From domain together, which makes the mismatch obvious.
Ask, in order:
- What is the domain in
header.from=? - What is the domain in
smtp.mailfrom=? Does it share an Organizational Domain with the answer to 1? - What is the domain in the DKIM
d=tag? Same question.
If the answer to 2 and 3 is "no", you have an alignment failure and the rest of this article applies. If the answer is "yes" but DMARC still fails, check whether you have published aspf=s or adkim=s.
Fix 2: Get the Vendor to Sign DKIM as Your Domain
This is the fix that matters most, because an aligned DKIM signature survives forwarding while SPF alignment does not.
Nearly every reputable sending platform supports this, usually branded as "custom domain", "authenticated domain", "sending domain" or "domain authentication". The mechanics are consistent:
- In the vendor's console, add your domain as a sending domain.
- The vendor issues DNS records to publish — typically CNAMEs at a selector host they choose, pointing into their infrastructure so they can rotate keys without involving you.
- Publish them in your DNS.
- Return to the vendor and click whatever confirms verification. Publishing the records without completing this step is the most commonly missed part.
Once done, the signature carries d=example.com rather than d=mail.sendingvendor.example, and DKIM is aligned.
# Confirm the selector resolves after publishing
dig +short CNAME s1._domainkey.example.com
dig +short TXT s1._domainkey.example.com
Use our DNS lookup tool if you do not have dig available.
Fix 3: Align SPF with a Custom Return Path
SPF alignment requires the envelope sender to be on your domain, which is a separate setting from the From address. Vendors call it the return path, bounce domain, envelope domain or MAIL FROM domain.
Configure it as a subdomain you delegate to the vendor, for example bounce.example.com, then publish whatever record the vendor specifies at that host. Under relaxed alignment bounce.example.com and example.com share an Organizational Domain, so SPF becomes aligned.
Two cautions:
- Adding the vendor's
include:to your main domain's SPF record does not create alignment. It makes SPF pass for the vendor's own envelope domain, which is exactly the situation you already have. Alignment is about which domain is in the envelope sender, not about which record lists the IP. - Every
include:you add consumes part of your 10-lookup budget. A dedicated bounce subdomain gets its own budget, which is another reason to prefer it.
Fix 4: Check Your Own Alignment Mode
If your sending is already on your own domain and DMARC still fails, inspect the policy you published:
dig +short TXT _dmarc.example.com
v=DMARC1; p=quarantine; adkim=s; aspf=s; rua=mailto:dmarc@example.com
adkim=s and aspf=s demand exact FQDN matches. If you send from notifications.example.com while signing with d=example.com, strict mode fails what relaxed mode would pass. Unless you have a specific reason for strict alignment, remove both tags and take the relaxed default:
v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com
Our DMARC generator builds a syntactically valid record.
What Not To Do
Do not set p=none and call it fixed. It stops the enforcement, not the failure. Your domain becomes freely spoofable while the underlying misalignment remains. p=none is a legitimate temporary state while you read aggregate reports and fix sources — it is not a destination.
Do not remove the DMARC record. No record means no policy, no reports, and no protection.
Do not add +all to SPF in an attempt to force a pass. It authorises the entire internet to send as your domain and does nothing for alignment, because the envelope domain is still the vendor's.
Do not change your From address to the vendor's domain. It would technically align, at the cost of every recipient seeing mail from example.sendingvendor.example instead of your brand.
Verify the Fix
Send a live message through the affected platform to a mailbox you control, then read the results. In Gmail use Show original; in Outlook on the web use View message details. You want the DMARC line to pass and at least one aligned identifier:
dkim=pass header.i=@example.com header.s=s1;
spf=pass smtp.mailfrom=bounce.example.com;
dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=example.com
The test is not "does DKIM pass" — it is "does the DKIM d= domain match the From domain". Check the domains, not just the verdicts.
Then confirm across your DMARC aggregate reports over the following week that the source now reports as aligned. One test message proves the configuration; the reports prove the whole sending path.
Prevention
- When onboarding any service that sends mail as your domain, complete domain authentication at the vendor before the first campaign, not after the first failure report.
- Prefer configuring both DKIM signing and a custom return path. Either one alone satisfies DMARC, but having both means a single break does not fail the message.
- Keep
rua=aggregate reporting on permanently and read it monthly. Alignment failures show up there as passing-but-unaligned sources long before anyone notices missing mail. - Use a subdomain per sending purpose, and let relaxed alignment do its job rather than reaching for strict mode.
- Reach
p=rejectin stages —none, thenquarantinewithpct=, thenreject— and only advance when the reports are clean.
Summary
- DMARC needs alignment, not just authentication — the passing domain must match the From domain
- Compare three domains in the headers:
header.from,smtp.mailfrom, and DKIMd= - Fix DKIM alignment first — it survives forwarding, SPF alignment does not
- Fix SPF alignment with a custom return path; adding an
include:does not align anything - Check for
aspf=s/adkim=sif your own domains already look right - Never "fix" it with
p=noneor+all— both remove protection instead of restoring alignment