How to read DMARC aggregate (RUA) reports
By Thomas · virtual CISO · June 16, 2026
Opened for the first time, a DMARC aggregate report looks like noise: a wall of XML full of IP addresses and pass/fail flags. But these reports are the single most useful thing DMARC delivers. They are the map that takes a domain from monitoring to enforcement — the only reliable way to discover everyone sending mail in that domain's name before the policy tightens. This guide explains what's inside, how to read it, and how to act on it.
What aggregate reports are
Once a DMARC record carries a rua= address (see what is DMARC for the basics), receiving providers — Google, Microsoft, Yahoo and hundreds of others — start sending a daily summary. Each report covers a 24-hour window and answers one question: of all the mail that claimed to be from the domain, where did it come from, and did it authenticate?
These are aggregate (RUA) reports — counts grouped by sending source, not copies of individual emails. (A separate, rarer kind called forensic or failure reports, RUF, can include redacted samples, but aggregate reports are the daily bread.) They arrive as XML, usually gzipped or zipped, attached to an email.
Anatomy of the XML
Every report has the same shape. Three parts matter:
1. Report metadata — who sent the report and the time window:
<report_metadata>
<org_name>google.com</org_name>
<report_id>14217...</report_id>
<date_range><begin>1718...</begin><end>1718...</end></date_range>
</report_metadata>
2. Published policy — the DMARC record the receiver saw for the domain that day. Useful for confirming a record propagated as expected:
<policy_published>
<domain>example.com</domain>
<p>none</p><adkim>r</adkim><aspf>r</aspf><pct>100</pct>
</policy_published>
3. Records — the heart of the report. One block per sending source, with a volume count and the authentication results:
<record>
<row>
<source_ip>203.0.113.10</source_ip>
<count>42</count>
<policy_evaluated><disposition>none</disposition><dkim>pass</dkim><spf>fail</spf></policy_evaluated>
</row>
<identifiers><header_from>example.com</header_from></identifiers>
</record>
That block reads as a sentence: "From IP 203.0.113.10, 42 messages claimed to be from example.com; DKIM aligned and passed, SPF did not." Because DMARC needs only one aligned pass, those 42 messages passed DMARC on the strength of DKIM.
The fields that decide everything
For each source, three things carry the verdict:
source_ipandcount— who sent, and how much. High-volume sources are the most important ones to get right.dkimandspfresults insidepolicy_evaluated— these reflect alignment, not just whether the mechanism passed in isolation. This is the number that matters: a source can pass raw SPF yet showspf: failhere because the domain didn't align with theFrom:.disposition— what the receiver actually did (none,quarantine,reject), based on the current policy.
A source where either dkim or spf shows pass is authenticated and safe to enforce against. A source where both fail is the problem set — it's either a legitimate sender not yet aligned, or a spoofer.
Turning reports into action
The workflow is always the same, and it's the whole game:
- Aggregating across reports. A single day from a single provider is a sliver. Many reports combined over a few weeks give the full picture of who sends for the domain.
- Identifying every legitimate source. That high-volume IP passing DKIM is probably the main mail platform. The one failing both might be the CRM, the billing system, or a tool a team set up without telling IT. Each one gets a name.
- Fixing alignment for the legitimate ones. The missing
include:goes into SPF, DKIM signing gets an alignedd=, until each real sender shows apass. - Watching the failures shrink. When the only
failsources left are unrecognized ones — spoofers — the policy is ready to tighten. - Ramping the policy. On to
quarantine, thenreject, with the reports staying clean throughout. The full sequence is in how to get to p=reject.
Reading as a habit, not a project
The workflow above only pays off if someone actually runs it. Report reading works best as a recurring ritual with a named owner, not a one-off audit: a short weekly review during the p=none phase, a closer look in the days that follow any DNS or policy change, and a quick glance after onboarding any new sending tool. Alongside the cadence comes a living inventory of sources — each IP or service identified, who owns it internally, and its current alignment status. That inventory is what survives staff turnover and vendor changes: months from now, nobody should have to rediscover that a given IP range is "the invoicing platform". Written down once and verified at each review, it turns every new report from an investigation into a simple diff.
Why people give up — and how not to
Reading raw XML by hand does not scale. A mid-size company can receive dozens of reports a day from many providers, each listing many IPs. Mapping a stream of IP addresses back to "oh, that's our Zendesk" is tedious and error-prone, which is exactly why so many domains collect reports for a while and then quietly stop at p=none. The reports were never the problem; making sense of them was.
The fix is to let software do the aggregation and translation. That's what Thomas, the virtual CISO, is built for: he ingests the aggregate reports, turns raw IPs and PTR records into recognizable service names ("a Mailchimp account", "an unconfigured SendGrid subaccount"), scores readiness over a rolling window, and names exactly which sources to fix before each step toward p=reject.
What aggregate reports don't say
Aggregate reports are powerful, but knowing their limits is what keeps wrong conclusions at bay:
- No message content. Aggregate reports contain counts and authentication results, never subjects, bodies or recipient addresses. They establish that a source sent mail under a domain's name and how it authenticated — not what the mail said. (A separate, rarer report type — forensic or failure reports, RUF — can include redacted samples, but many providers don't send them at all for privacy reasons.)
- A delay of roughly a day. Reports cover a 24-hour window and arrive afterward, so the view is always yesterday, not this minute. A record change draws no real-time feedback; a day or two passes before it shows up. That daily cadence is baked into the standard — why reports arrive once a day covers the mechanics.
- Per-source, not per-message. A row aggregates many messages from one IP with the same result. An individual email can't be traced through aggregate data alone.
- Only participating receivers. Most large mailbox providers send reports, but not every receiver does. The reports represent the large majority of a domain's mail, not literally all of it.
- Raw IPs, not names. The report says
198.51.100.7, not "the Zendesk instance". Mapping addresses back to services falls to the administrator — and it's the single most time-consuming part of the job.
None of this diminishes their value; it just means aggregate reports are a map, not a live camera. They read as trends over weeks, not as moment-to-moment telemetry, and pair best with tooling that turns IPs into recognizable senders.
Three common reading traps
A few reflexes keep the wrong conclusion at arm's length:
- Confusing a mechanism pass with alignment. The
dkim/spffields inpolicy_evaluatedreflect alignment. A source can pass raw SPF and still showspf: failhere because its envelope doesn't align with theFrom:. Those fields always answer "aligned?", not "did the mechanism technically pass?". - Panicking over unknown IPs. A spike of small, scattered sources is often forwarding (a receiver re-sending the mail) rather than an attack. Volume and regularity come before any verdict of spoofing: a spoofer chases volume, while forwarding leaves a long tail of one-message accounts.
- Forgetting what
dispositionmeans. Atp=none,dispositionstaysnoneeven whendkimandspffail — that's expected, since nothing is being enforced yet.disposition: nonedoesn't mean "all good": it'sdkim/spfthat reveal whether a source is healthy. - Reading a single report in isolation. One report from one provider on one day is a fragment, not a verdict. A source can look broken in Tuesday's Google report and fine in the weekly aggregate once providers are combined. A source is judged on the trend across several days, never on one XML file.
DMARCbis and reporting (RFC 9990)
DMARCbis (May 2026) split the specification into three RFCs: 9989 for the protocol, and notably 9990, now dedicated to the aggregate reports described here. The spirit doesn't change — same source / volume / result blocks — but two details will surface in the reports over time:
- The
<policy_published>block will no longer show<pct>(the tag is gone) and may include<np>, the policy for non-existent subdomains. Apctstill showing up is simply a receiver that hasn't updated yet. - Organizational-domain discovery now relies on the DNS Tree Walk rather than the Public Suffix List, which makes attribution more predictable.
In practice, the reading method doesn't move. Worth noting, though: during the transition, reports may mix the old and new formats depending on the provider.
Getting the reports flowing
Two things get it started: a DMARC record with a rua= address, and somewhere to send the reports. The exact syntax of that tag — including the extra step when reports go to another domain — is covered in setting up the rua address. The fastest way is a free DMARC monitoring mailbox that ingests and parses the XML automatically — one DNS line, and the daily reports turn into a readable dashboard instead of a folder of attachments.
The starting point is a check of the current setup with our free analyzer — it shows whether a rua= address exists at all and how the sources are aligning today. From there, creating an account collects and reads the reports continuously, with Thomas translating every source and pointing the way to enforcement.
For the fundamentals, what is DMARC and how SPF, DKIM and DMARC work together are where to begin.
Related guides
- Not receiving DMARC reports: the causes and the fix
A DMARC record is published, but no reports arrive. Here are the possible causes, in the order to check them, from the most common to the most subtle.
- Configuring the DMARC rua address (without getting tripped up)
The rua address receives the DMARC aggregate reports. The syntax is simple, but sending to an external domain hides an authorization trap many discover too late.
- DMARC forensic reports (RUF) and privacy: what to know
DMARC RUF reports can contain personal data from senders. What RUF contains, why few ISPs still send them, and how to stay GDPR-compliant.
About the author
Thomas — Thomas is the virtual CISO of DMARC.com: a copilot specialized in email authentication that walks organizations from p=none to p=reject without breaking their mail. His guides draw on real data from the DMARC Observatory and the RUA reports the platform analyzes.
