How to read a DMARC aggregate report
Last updated 2026-08-21
An aggregate report is a small XML file with a hostile filename, and there is exactly one idea in it that matters. Everything else is bookkeeping.
Open it
Reports arrive as .xml.gz or .zip attachments named something
like google.com!example.com!1755043200!1755129599.xml.gz. The numbers are the
Unix timestamps of the reporting window.
If xmllint is not installed, any editor will do; the formatting just makes it
readable. A day's report from a large receiver is a few kilobytes. If you would rather
not read the XML at all, our
DMARC report analyzer takes the same file and
prints what the rest of this guide teaches you to look for. It needs no account and keeps
nothing.
The structure
Three parts: who is reporting, what policy they saw, and one record per sending source.
The one idea
Look at that record again. In auth_results, DKIM says
pass. In policy_evaluated, DKIM says
fail. Both are correct, and the difference between them is the whole
point of the format.
-
auth_resultsis the raw outcome. The signature verified. It verified forvendor.net, which is right there in thedomainfield. -
policy_evaluatedis the outcome after alignment.vendor.netis notexample.com, so for DMARC purposes DKIM failed.
Read policy_evaluated when you want to know whether DMARC passed. Read
auth_results when you want to know who to go and talk to. Every confusing
report resolves once you hold those two apart.
Field by field
| Field | What it tells you |
|---|---|
| source_ip | The server that connected. Your primary key for identifying a sender. |
| count | Messages from that IP with that exact outcome in the window. |
| disposition | What the receiver did: none, quarantine or reject. |
| header_from | The domain in the visible From address. Watch for subdomains here. |
| auth_results/dkim/domain | The signing domain. Names the vendor. |
| auth_results/spf/domain | The envelope sender domain. Also names the vendor. |
| policy_published | What the receiver saw in your DNS at the time. Useful for confirming a change went live. |
Identify the source
Given an IP and nothing else:
Reverse DNS usually names the provider outright. Where it does not, the
auth_results domains give it away, because a vendor signing with its own
domain has told you exactly who it is.
The four patterns
-
Everything passes. One or two IP ranges, high counts, both columns
passing in
policy_evaluated. Your main mail flow. Nothing to do. -
SPF fails, DKIM passes, many IPs, low counts each. Forwarding.
Recipients auto-forwarding your mail to another provider. DMARC passes because DKIM
aligns, and there is nothing to fix. If DKIM were not working, this is the traffic you
would be destroying at
p=reject. - One IP range, steady counts, both failing, an obvious vendor in auth_results. A platform sending as you without domain authentication. This is your work queue. The provider pages have the records.
- Scattered IPs, small counts, no recognisable signing domain, often from residential ranges abroad. Spoofing. Nothing to fix, and the reason for finishing the ramp to reject.
Doing this at scale
By hand is the right way to read your first ten reports and the wrong way to run a domain. You will get twenty to fifty files a week, many from receivers you have never heard of, and a fair number malformed in small ways.
DomainCanary is our product; weigh this paragraph accordingly. We take those reports, parse the malformed ones too, and email one summary a week with the pass rate and the sources that changed. On the paid plans we also write the day a report first shows a source your domain has never seen failing, rather than holding it for Monday; a sender already in your history waits for the digest. We cover aggregate reports only, not forensic ones. Point the reports at us and your first domain costs nothing.
The reason to read one by hand at least once is that the parsed views all make the same simplification: they show you pass and fail, and hide the distinction between raw results and aligned ones. That distinction is where every confusing DMARC problem lives, and once you have seen it in the XML you stop being surprised by it in a dashboard.
Run the ramp on real reports
Every step in this guide depends on a few weeks of aggregate reports. We parse them and mail you a weekly summary: the senders that used your domain, what failed, and when tightening the policy is safe. Paid plans email you the day a new source first fails. Your first domain is free.
Get the weekly digestNo card · 12+ months of history · The free plan does not expire
Questions
Why does my report show SPF passing and DMARC failing for the same message?
The auth_results block records the raw SPF result. The policy_evaluated block records the result after alignment. A pass in the first and a fail in the second means SPF authenticated a domain that is not the one in your From header.
Do aggregate reports contain message content?
No. They are counts grouped by source IP and authentication outcome, with no subjects, no recipients and no bodies. Forensic reports (ruf) do carry message detail, which is why most large receivers stopped sending them.
How often do reports arrive?
Once a day per receiver for most, covering a 24 hour window. Small receivers send irregularly or not at all, so a source that appears in one report and not the next has usually not gone away.
Keep reading
Checking as you go? The DMARC checker reads the policy you are ramping, the SPF and DKIM checkers show whether your senders will survive it, and the report analyzer reads an aggregate report you already have. No signup.
DomainCanary is a DMARC monitoring service that turns your domain's aggregate reports into one weekly email.