Domain Health · DMARC · Reading reports
SPF fail, DMARC pass: reading a DMARC report row
Your first DMARC aggregate report arrives, and one line says SPF fail but DMARC pass. That's usually fine, sometimes a clue, and occasionally a sender you need to fix. Here's how to tell which, field by field.
The row
Aggregate reports are XML files (usually zipped) that receivers such as Gmail send to the address in your DMARC record's rua= tag, normally once a day. Each <record> groups messages from one sending IP. Here's the pattern, simplified (the IP is a documentation example):
<row>
<source_ip>192.0.2.25</source_ip> <count>1</count>
<policy_evaluated><disposition>none</disposition><dkim>pass</dkim><spf>fail</spf></policy_evaluated>
</row>
<identifiers><header_from>example.com</header_from></identifiers>
<auth_results>
<dkim><domain>example.com</domain><result>pass</result></dkim>
<spf><domain>example.com</domain><result>softfail</result></spf>
</auth_results>
Our own first report from Google, for mistermarbi.com, had exactly this shape: one message, DKIM pass, SPF fail, DMARC pass, disposition none.
Which fields matter
policy_evaluatedis the DMARC verdict. Itsdkimandspfvalues mean "passed and aligned with the From domain", not just "passed".auth_resultsis the raw result: which domain SPF and DKIM were checked for, and what they returned. Compare the domains there withheader_from.dispositionis what the receiver did:none,quarantineorreject. Withp=noneit's alwaysnone, whatever the result.
Why DMARC passed
DMARC needs one of SPF or DKIM to pass and align with the From domain, not both. In the row above, DKIM passed for example.com, the same domain as header_from, so DMARC passes even though SPF failed. That's DKIM doing its job.
The four combinations
- DKIM pass, SPF pass → healthy.
- DKIM pass, SPF fail (this page) → DMARC passes. Usually forwarding, or a sender that isn't in your SPF record but signs with your key. See below to tell them apart.
- DKIM fail, SPF pass → DMARC passes on SPF alone. Fragile: it'll fail as soon as the message is forwarded. Turn on DKIM signing for that sender.
- DKIM fail, SPF fail → DMARC fails. Either a real sender of yours is misconfigured, or someone is spoofing your domain. This is the row to act on.
Forwarding, or a sender you forgot?
Look up who owns source_ip (a reverse DNS lookup, or a WHOIS/IP lookup tool), then:
- It belongs to a mailbox or list provider, the count is small, and DKIM passes → almost certainly forwarding: a recipient's mailbox automatically forwards to Gmail, or a mailing list re-sends your message. The forwarder's IP isn't in your SPF record (and shouldn't be), so SPF fails; your DKIM signature survives the trip. Nothing to fix.
- It belongs to a service you use (a newsletter tool, store platform, help desk), or the count is large and recurring → it's one of your senders. If DKIM already passes, you can leave SPF alone or add the service's include, but watch the 10-lookup limit. If it later shows DKIM fail too, fix it before you tighten your policy.
- You don't recognise it and DKIM fails as well → likely spoofing. That's what
p=quarantineorp=rejectstops, once your real senders all pass.
Before you tighten your policy
Rows like this one are why you collect reports for a few weeks on p=none first. When every source you recognise shows DMARC pass (with DKIM pass on each), moving to p=quarantine won't affect your real mail, including forwarded copies, because those pass on DKIM. If a recognised sender passes only on SPF, add DKIM for it first.
Quick reference
policy_evaluated= aligned result (what DMARC used).auth_results= raw result.- DMARC pass needs one aligned pass: SPF or DKIM.
- SPF fail + DKIM pass from a provider IP, at low volume: forwarding, usually harmless.
- Both fail: investigate before moving past
p=none.
Related: DMARC checker · SPF checker · DKIM checker · Pre-holiday sending check