Skip to content
Authentication

DMARC aggregate reports: what they contain and how to read them

Aggregate reports are DMARC's feedback loop: daily XML files showing every source sending as your domain. The format, a worked example, and what to look for.

Aggregate reports are the feedback loop that makes DMARC useful. Without them, a domain owner is publishing policy in the dark. Every receiving domain that processes mail from a domain sends an aggregate report, typically once per day. The report arrives as a gzip-compressed XML file attached to an email, covers a specific time period, and contains one record block for each unique combination of source IP, authentication results, and policy outcome.

Reading a report record

One record block
1<record>
2  <row>
3    <source_ip>198.51.100.25</source_ip>
4    <count>1284</count>
5    <policy_evaluated>
6      <disposition>none</disposition>
7      <dkim>pass</dkim>
8      <spf>fail</spf>
9    </policy_evaluated>
10  </row>
11  <identifiers>
12    <header_from>yourdomain.com</header_from>
13  </identifiers>
14  <auth_results>
15    <dkim>
16      <domain>yourdomain.com</domain>
17      <result>pass</result>
18      <selector>selector1</selector>
19    </dkim>
20    <spf>
21      <domain>esp.example.com</domain>
22      <result>pass</result>
23    </spf>
24  </auth_results>
25</record>

The record above reads as follows. A total of 1,284 messages were sent from IP 198.51.100.25 with yourdomain.com in the From: header. DKIM passed, and because the signing domain was yourdomain.com, the result is aligned. SPF passed for esp.example.com, but that domain does not match the From: domain, so SPF is not aligned. Because DKIM passed with alignment, DMARC passed overall. The disposition was none, matching the published policy.

Three things to look for

Unknown source IPs: any IP sending mail as the domain that the owner does not recognize is either a forgotten service or an attacker spoofing the domain. Look up the IP's reverse DNS and investigate it. Most turn out to be legitimate tools someone adopted without telling anyone, which is exactly the inventory the monitoring phase exists to build.

Alignment failures on known senders: this is the most common issue during rollout. An ESP passes SPF, but the SPF domain is the ESP's, not the customer's. The fix is almost always configuring custom DKIM signing through the ESP's dashboard, so the DKIM d= domain matches the From: domain; the mechanics are covered in the alignment entry.

Sudden volume spikes: a surge of messages from unfamiliar IPs usually means someone is running a spoofing campaign against the domain. This is exactly what p=reject prevents, and watching the spike's size at p=none is watching the problem enforcement will solve.

Tooling: nobody reads XML by hand for long

Parsing raw XML reports by hand does not scale beyond a handful of reports. A mid-size domain receives dozens daily from Google, Microsoft, Yahoo, and smaller receivers, and the value is only visible after aggregation across reporters and days. parsedmarc is a solid open-source option that ingests the report mailbox and exports to Elasticsearch or CSV with ready-made dashboards. Hosted options (EasyDMARC, Valimail, Postmark's DMARC tool, dmarcian and peers) trade money for the parsing, enrichment, and alerting layers. Either way, point rua at a dedicated address, never a human inbox.

What about forensic reports?

The ruf tag requests forensic reports: per-message failure samples with headers and sometimes content. Most major providers do not send them for privacy reasons, so build the monitoring practice entirely on aggregates. The record tags entry covers the ruf mechanics and the authorization record needed when reports go to a different domain than the one being monitored.

Frequently asked questions

How soon do reports arrive after publishing rua?
Typically within 24 to 48 hours, as receivers complete their daily reporting cycles. No reports after several days usually means a typo in the rua address, a missing authorization record for an external report domain, or simply no mail volume reaching reporting receivers.
Why do report totals not match my sending logs?
Reports count what each receiver saw claiming your domain, including forwarded copies and spoofed mail you never sent, and not every receiver sends reports. Treat the data as a census of claims on the domain, not as delivery accounting.
What does disposition=quarantine mean when my policy is p=none?
Receivers may override the published policy in either direction and record what they actually did. A quarantine disposition under p=none means the receiver's own filtering junked the message independently of DMARC.
How long should report data be kept?
At least 13 months of parsed data. Year-over-year comparison catches seasonal senders (annual renewals, billing cycles) before a policy change breaks something that only sends every December.

Key takeaways

  • Aggregate reports arrive daily as gzipped XML, one record per source IP and result combination
  • Read both layers: auth_results shows raw outcomes, policy_evaluated shows alignment for your domain
  • Watch for unknown source IPs, alignment failures on known senders, and sudden volume spikes
  • Use parsedmarc or a hosted platform; raw XML reading does not scale past the first week
  • Forensic (ruf) reports are mostly not sent; aggregates are the data source to build on