Publishing a DMARC policy is the single most effective thing you can do to stop someone from spoofing your domain. The record lives in DNS and tells every receiving mail server on the planet, Gmail, Microsoft 365, Yahoo, iCloud, how to treat messages that claim to be from you but fail SPF and DKIM.
But DMARC is not only about enforcement. It is also a feedback loop. When you build your record with the DMARC Generator, you include a rua tag pointing at an inbox that should receive aggregate reports, something like v=DMARC1; p=none; rua=mailto:[email protected];. Once that record is live, every receiving server that handles your mail starts sending you a daily summary of what it saw.
That is where the trouble starts. For a mid-sized company, "a daily summary from every receiver" means hundreds of emails a day, each carrying a compressed attachment (.xml.gz or .zip). Inside is dense, machine-formatted XML listing thousands of sending IPs, alignment results, and dispositions. Nobody reads that by hand and lives to tell about it. The DMARC Report Parser exists to turn that pile of XML into something you can actually act on.
What a raw DMARC report actually looks like
Every aggregate report follows the same official schema. Here is a trimmed-down example so you can see the shape of it:
<feedback>
<report_metadata>
<org_name>google.com</org_name>
<email>[email protected]</email>
<report_id>1234567890123456789</report_id>
<date_range>
<begin>1774137600</begin>
<end>1774224000</end>
</date_range>
</report_metadata>
<policy_published>
<domain>yourcompany.com</domain>
<p>none</p>
<sp>none</sp>
<pct>100</pct>
</policy_published>
<record>
<row>
<source_ip>198.51.100.42</source_ip>
<count>1450</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>fail</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>yourcompany.com</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>yourcompany.com</domain>
<result>fail</result>
</dkim>
<spf>
<domain>yourcompany.com</domain>
<result>pass</result>
</spf>
</auth_results>
</record>
</feedback>
That is one <record>. A real report has hundreds of them, and you get dozens of reports a day. Assessing by eye whether your legitimate mail is authenticating correctly is simply not realistic at that volume.
How the parser handles it
The parser does all the work in your browser. Paste raw XML, or drag and drop .xml, .xml.gz, or .zip archives straight in. From there it extracts and calculates a few things:
- Reporting organization and date range — who sent the report (Google, Microsoft, Comcast) and the exact window it covers, converting the Unix epoch timestamps into readable dates.
- Published policy — the policy that was actually enforced during that period, whether
p=none,p=quarantine, orp=reject. - Source IP aggregation — messages grouped by originating IP, with total volume and geographic origin.
- SPF and DKIM alignment — and this is the part people miss. Raw SPF or DKIM passing is not the same as DMARC alignment. A message can pass SPF on a technicality while the envelope-from domain fails to match the visible Header From, in which case DMARC alignment still fails. The parser separates the two.
- Disposition — what the receiver actually did: delivered, quarantined, or rejected.
Here is what a parsed summary looks like once the noise is stripped out:
| Sending Source | Count | SPF | DKIM | DMARC Align | Disposition |
|---|---|---|---|---|---|
| Google (209.85.220.41) | 4,210 | PASS | PASS | PASS | Delivered (None) |
| Mailchimp (198.2.178.52) | 850 | PASS | FAIL | FAIL | Delivered (missing DKIM key) |
| Rogue botnet (192.0.2.14) | 12,400 | FAIL | FAIL | FAIL | Quarantined/Rejected |
One glance tells the whole story. Google is clean. Mailchimp is a real service you use but its DKIM key was never published, so it is failing alignment and needs fixing. And that botnet is an outright spoofer that should be blocked.
The three phases to full enforcement
The endpoint you want is p=reject, which tells the world to throw away any unauthorized mail pretending to come from you. But jumping straight there without reading your reports is reckless. You will almost certainly block legitimate corporate mail, the marketing platform, the HR system, the billing service, and only find out when someone complains. The reports are how you avoid that. Work through them in order:
Monitoring (
p=none). Publish a record withp=noneso receivers report failures without blocking anything. Collect reports for two to four weeks and feed them to the parser. It shows you every service sending on your behalf, the legitimate ones (Salesforce, Zendesk) alongside the spoofers.Remediation and alignment. Now fix what the breakdown surfaced. Add missing IPs or
include:directives to your record, which you can check against the SPF record lookup; if that record is bumping against the 10-lookup limit, the SPF Flattening tool helps. Publish DKIM keys for third-party platforms like Mailchimp and HubSpot, and confirm them with the DKIM record lookup. Finally, verify the Header From domain aligns with your SPF and DKIM signing domains.Strict enforcement (
p=quarantine→p=reject). Once the parser shows 100% of your legitimate sources passing DMARC, move top=quarantineso unauthenticated mail goes to spam. When that holds steady, switch top=rejectand block it outright. At that point, spoofing your exact domain stops working. You can confirm the live policy any time with the DMARC record lookup.
A real scenario: the phishing run nobody saw
A regional credit union had recently published a p=none record. Its IT team was getting dozens of .xml.gz files a day from Microsoft and Google and, understandably, never had time to decompress and read them.
One afternoon the IT director dropped a week's worth of archives into the parser. The result was ugly. Legitimate employee mail through Google Workspace was passing fine, but a suspicious IP range in another country had pushed more than 45,000 messages over the weekend using the union's exact domain, every one of them failing SPF and DKIM. Because the domain was still on p=none, all 45,000 phishing emails aimed at the union's own customers had landed in inboxes.
With clear proof that no legitimate tool was failing, the director moved the record to p=reject. The next day's scan told the rest: the attacker tried another 20,000 messages, and every one was rejected at the boundary.
The takeaway
DMARC reports are only useful if you can read them, and at real volume you cannot read them without help. Decompressing, parsing, grouping by source, and separating raw authentication from true alignment is exactly the tedious work the parser takes off your hands. Start on p=none, spend a couple of weeks reading what comes back, fix your legitimate senders, and then close the door with p=reject. That is the whole game.