A DMARC record with rua= has a side effect few people are prepared for: from the next day onward, messages arrive daily with ZIP or GZ files attached, from Google, Microsoft, Yahoo, and from mail servers whose names you have never heard. Inside is XML. Most people look twice and then set up a rule that sweeps the whole pile into a folder.
That is a shame, because these files answer a question nothing else can: who is actually sending mail under my name?
What a report contains — and what it does not
An aggregate report is a tally, not a collection of messages. It contains no subject lines, no recipients, no content. For one day and one receiver it says: these IP addresses sent this many messages carrying your domain in From:, and this is how they turned out.
The structure is always the same. Learn it once and you can read the file without any tool.
policy_evaluated and auth_results: one is the result, the other the reason.One record in the original
Here is a single record, unpacked and indented:
<record>
<row>
<source_ip>198.51.100.24</source_ip>
<count>417</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>fail</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>company.com</header_from>
</identifiers>
<auth_results>
<spf><domain>company.com</domain><result>pass</result></spf>
</auth_results>
</record>
Read out: on that day, 417 messages came from 198.51.100.24 carrying company.com as the visible sender. SPF passed and was aligned, DKIM was not — there was no signature at all here. Since one aligned path is enough, DMARC passed. disposition: none says the receiver took no action.
The trap: two results with the same names
The words spf and dkim appear twice in that block, in two different places, with two different meanings:
- In
auth_resultsis the raw result: did the check itself pass? - In
policy_evaluatedis the result after alignment: does that pass count for DMARC as well?
A pass above and a fail below is the single most common finding, and it describes no contradiction but a source that sends legitimately, only under someone else's domain. Why that happens is covered in the article on alignment.
What a first report typically turns up
Anyone switching DMARC on finds, in the first two weeks, more sending sources than expected. The candidates repeat across organisations:
| Source | Typical finding |
|---|---|
| Your own mail server | SPF and DKIM aligned — the uneventful part |
| Newsletter service | SPF not aligned, DKIM on the provider domain |
| Ticket or CRM system | sends under the company domain with no DKIM at all |
| Invoicing or shop software | its own sending path, often forgotten for years |
| Monitoring, backup, printers | small counts, fixed IP, usually from your own network |
| Forwarders | foreign IP, SPF broken, DKIM intact |
| Unrelated senders | changing IPs, both checks failed, small volumes |
The last row is the reason DMARC gets introduced — and it is almost always the smallest. The work sits in the rows above it: every legitimate source has to be found and configured before the policy can be tightened.
The order that works
- Set
p=nonewithrua=. This changes nothing about delivery and only turns the reports on. - Collect for two to four weeks. Not less: the monthly invoice run and the newsletter that goes out every three weeks will otherwise never appear.
- List the sources and account for each. Every IP that sent more than a handful of messages needs a name.
- Establish alignment, usually via DKIM at the provider in question.
- Only then tighten — in steps, using
pct=, which sets the share of messages the policy applies to.
Step three is where projects stall, and for an uncomfortable reason: some sources can only be identified by asking around the company who set up a service six years ago.
The forensic reports
Next to rua= there is ruf=: notifications about individual failed messages, with headers and sometimes content. In practice almost none arrive. The reports contained personal data belonging to third parties, and most large providers stopped sending them for that reason. You can set ruf=; you should expect nothing.
Do you need a tool for this?
For a couple of domains and a manageable volume it is enough to unpack the attachments and skim the records — the interesting lines are the ones with an unknown source_ip and two failures in policy_evaluated. Once you are into double-digit domain counts or high volume this stops being readable, and an analysis that merges reports and resolves IPs saves hours.
The point is a different one: the reports are not complicated. They are only packaged in a way that makes them look complicated.