14 June 2026 · 14 min read
A DMARC aggregate report is one of the most useful documents your domain will ever generate, and one of the least read. Publish a record with a rua= tag and, within a day or two, gzip-compressed XML files start arriving from Google, Microsoft, Yahoo, Comcast and a long tail of mailbox providers you have never heard of. Each file describes, source by source, how mail claiming to be your domain authenticated across thousands of messages. That is the raw material for every decision you will make about email authentication. The trouble is that in its raw form it is unreadable, it arrives faster than any human can process it, and it answers your real question only after you have done a great deal of mechanical work first. Aggregate report analysis is the work of turning that pile of XML into source lists, alignment results and disposition counts you can actually act on, and then using those to move a domain safely from p=none to p=reject.
This article walks through what is inside an aggregate report, what stops people reading them by hand, how a parsing pipeline reconciles thousands of rows into a handful of answers, and how those answers carry a domain to enforcement without breaking legitimate mail along the way.
Why raw aggregate XML defeats people
The format is the first obstacle. An aggregate report is an XML document, almost always gzipped, sometimes wrapped in a ZIP. A medium-sized organisation publishing rua=mailto:reports@yourdomain.com receives dozens of these every day, one batch per provider per reporting window, which is usually 24 hours. Open one file in a text editor and you get nested tags describing source IP addresses, message counts and authentication results. Open thirty of them and you stop.
The volume is the second obstacle. A single busy day can produce tens of thousands of individual rows once you flatten every report. Each row is a <record> describing one sending source and one combination of results, with a count attached. To answer "is my legitimate mail passing", you have to read every row, group by source, add up the counts and separate the pass results from the fail results. To answer "is anyone spoofing me", you have to do the same again and then work out which of the failing sources you actually own. By hand, across dozens of files a day, this is not a task anyone sustains.
The inconsistency is the third obstacle. Providers do not agree on much. Google sends one large daily file. Some senders send tiny ones several times a day. A few send malformed XML that breaks a naive parser outright. The same sending source appears under three different provider reports with three different counts, and you are expected to add them together. Timezones differ. Schema versions differ. The result is that the information you actually want, buried under all of this mechanical noise, is "is my real mail passing and is anyone forging my domain", and that signal almost never reaches a human.
This is the gap that keeps domains stuck. Most domains that publish DMARC never move past p=none. The record monitors, the reports arrive, and then they sit unread in an inbox. Without parsing those reports you cannot see who sends as you, so you never gain the confidence to enforce, so the policy never blocks a single spoofed message. The reports are the entire point of DMARC, and they are the part almost everyone skips. You can confirm whether your own record even has a working reporting address with the DMARC checker, and if you have a single file to hand you can paste it into the DMARC report analyzer to see one report decoded; the product described here is what happens when that decoding runs continuously across every report, every day, for every domain you own.
What is actually inside a report
It helps to be precise about what an aggregate report does and does not contain, because the name misleads people. It is not a copy of your email. There are no subject lines, no bodies and no recipient addresses. An aggregate report is a statistical summary of authentication outcomes, grouped by sending source over a reporting window.
The document has two parts. The header, in the <report_metadata> and <policy_published> sections, records who sent the report, the date range it covers, a unique report ID, and the DMARC policy the receiver saw on your domain at the time: your p=, your sp=, your alignment modes and your pct=. That second part is quietly valuable, because it tells you what policy each receiver actually observed, which is how you catch a record that has drifted or been overwritten.
The body is a series of <record> elements. Each record describes one distinct combination of source and result, and carries these facts:
- Source IP. The server that sent the mail, for example
209.85.220.41. - Message count. How many messages that source sent with that exact result combination in the window.
- Header From domain. The visible From domain the message claimed, the one a human reads.
- Disposition. What the receiver actually did with the mail:
none,quarantineorreject. - SPF result and the domain it checked.
pass,fail,softfail,neutralorpermerror, plus the domain SPF authenticated. - DKIM result and the signing
d=domain.passorfail, plus which domain signed. - SPF alignment and DKIM alignment. Whether each authenticated domain matches the Header From domain.
That last pair is where DMARC lives. A message can show an SPF pass and still fail DMARC, because SPF passed for the envelope domain rather than the visible From domain. DMARC adds alignment: the domain that SPF or DKIM authenticated must match the domain a human sees in the From field, under either strict or relaxed matching. The aggregate report tells you, source by source, whether your mail was both authenticated and aligned, and that is exactly the question that decides whether you can safely enforce. If the alignment vocabulary is unfamiliar, the glossary defines identifier alignment, relaxed and strict modes, and the difference between the envelope and header domains.
From XML to structured rows: the ingestion pipeline
Turning that format into decisions is a pipeline, and each stage removes a specific kind of noise. Point your rua= tag at a reporting address managed for your domain and the pipeline starts on its own; there is nothing to download and no XML to open.
Decompress and validate
Every inbound report is decompressed, whether it arrives as gzip or as a ZIP. It is then validated against the DMARC aggregate schema before anything trusts its contents. This stage matters more than it sounds, because some providers ship malformed XML that crashes a hand-rolled parser mid-file. A file that fails validation is quarantined and logged rather than silently discarded, so one broken report from one provider never costs you a day of data and never goes unnoticed. The header is read here too, capturing the policy each receiver observed.
Parse into rows
The validated XML is flattened into structured rows, one per source and result combination, with the count preserved. At this point the data stops being a document and becomes a table you can query: source IP, From domain, SPF result and domain, DKIM result and domain, both alignment flags, disposition and count. Everything downstream operates on these rows.
De-duplicate and reconcile
Providers overlap heavily. The same sending source appears in reports from Google, Yahoo and a regional ISP, each counting only the mail it received. Reconciliation groups those by source, by reporting window and by provider, so you see one honest total per source instead of the same mail counted several times over. Reports also arrive twice, which genuinely happens, and a duplicate file is dropped on a content hash rather than added again. Without this stage your volumes are inflated and your pass rates are wrong.
Resolve and enrich
A bare IP address means nothing to most people, so each sending source is resolved to a recognised service wherever possible: your own mail servers, Google Workspace, Microsoft 365, a marketing platform, a CRM, a helpdesk, a payroll provider. Reverse DNS, published SPF ranges and known sending infrastructure all feed this. Anything that cannot be mapped to a known service is flagged as unknown, and unknown is precisely where your attention belongs, because it is either shadow IT you forgot about or someone forging your domain.
What the rows turn into
After ingestion you stop looking at files and start looking at answers. The same data, parsed and reconciled, collapses into a small number of views, each mapping to a decision you have to make.
Source lists
The central view is a list of every source that sent mail claiming to be your domain, with its message volume, its pass rate and its resolved identity. Legitimate, well-configured services sit at the top with high pass rates. Beneath them sits the part that earns its keep: sources you could not identify, and sources failing authentication. This list is usually the moment an organisation discovers a forgotten application still sending invoices from a subdomain, a department that signed up to a tool nobody told IT about, or an old monitoring box that has been emailing alerts off an unsigned server for years. You cannot enforce until every legitimate source on this list is authenticated and aligned, and the source list is the only place they are all enumerated.
Pass-rate trends
A single line per domain showing the percentage of your mail that passed DMARC each day. Onboard a new sending service or fix a misconfigured one and the line moves, and you see the effect within a day. A sudden dip is a signal that something changed: a vendor rotated infrastructure, a DKIM key expired, or a new sender started without telling you. Trend matters more than any single day's number, because enforcement is a question of watching the legitimate pass rate climb toward 100 percent and stay there.
Alignment breakdowns
For each source the result splits into SPF alignment and DKIM alignment, reported separately, because the two behave very differently in the wild. SPF does not survive forwarding: a source can pass SPF when it sends directly and fail it the moment a mailing list or a forwarding rule re-sends the message from a different server. DKIM, being a cryptographic signature on the message itself, usually survives forwarding intact. Seeing the split per source tells you whether a sender is safe to rely on for alignment as it stands, or whether you need to get its DKIM signing working before you tighten policy. A source that passes only via SPF is a source that will start failing as soon as its mail is forwarded, and the alignment breakdown is where you catch that before it bites. You can confirm a specific record with the SPF checker and the DKIM checker.
Disposition
Disposition is what the receiver actually did, and it is the column people most often overlook. At p=none every message is delivered regardless of result, so a failing spoof shows a disposition of none: it was delivered. As you move policy to quarantine and then reject, the disposition on those same failing sources changes to match, and you can watch enforcement take hold source by source in the data itself. Disposition is how you confirm your policy is doing what you intended rather than what you assumed.
Threat detection
Sources that send as you, fail authentication, and resolve to no service you use are the spoofing and phishing attempts. Picture a fake invoice going out from accounts@yourcompany.com off a server in a region you do not operate in: it appears in the reports with a failing SPF result, a failing DKIM result, and a disposition that depends entirely on your policy. At p=none it was delivered to your customer. Surfacing these as threats lets you both see the abuse and understand what your policy is, or is not, doing about it, which is often the argument that gets enforcement approved internally.
Reading reports across a whole estate
Most organisations do not own one domain. They own the primary brand, a few country variants, a couple of acquired companies, a parked defensive domain or two, and a dedicated sending subdomain for marketing mail. Single-domain tooling forces you to read each of these in isolation, which is exactly how the dangerous one gets missed.
A multi-domain roll-up reconciles every domain into one view: aggregate pass rates across the whole estate, one consolidated and de-duplicated list of every sending source touching any of your domains, and a ranking of which domains sit at p=none versus p=quarantine versus p=reject. A domain you half-forgot you owned, sitting wide open with no DMARC record and no enforcement, is precisely the one an attacker will choose to forge, because it carries your brand and defends nothing. The roll-up is where that domain stops hiding. The same view also exposes a sending source that touches three of your domains but is properly authenticated on only one, which is the kind of inconsistency that no per-domain report can show you. This consolidated reporting is the core of the analytics product, and it sits alongside the managed DMARC, SPF and DKIM services that fix what the reports reveal.
Using the analysis to reach enforcement
The whole purpose of reading these reports is to move from monitoring to blocking without ever blocking your own mail. That is a sequence, and each step is driven directly by what the parsed reports tell you. Doing it blind, by editing DNS and hoping, is how organisations end up bouncing their own invoices and rolling back in a panic.
- Publish
p=noneand collect. Start in pure monitoring mode with reporting switched on. Nothing is blocked. Let reports accumulate for one to two weeks so the source list is reasonably complete, including monthly senders like payroll or billing that only appear at certain times. The DMARC generator produces a correct starting record, and you can confirm reporting is wired up with the DMARC checker.
- Inventory every source. Work down the parsed source list and account for each one. Every legitimate sender must be identified and brought to a passing, aligned state, which usually means adding it to your SPF policy or, better, getting it to sign with DKIM under a domain that aligns. The unknown sources are triaged here: a real service nobody registered, or a spoofer. This step ends when the source list contains no unexplained legitimate volume.
- Fix alignment, lean on DKIM. Use the alignment breakdown to find sources that pass authentication but fail alignment, and the sources passing only via SPF that will break on forwarding. Prefer DKIM alignment wherever you can, because it survives the forwarding paths SPF cannot. Watch the pass-rate trend climb as each fix lands.
- Move to
p=quarantine, often withpct. When the legitimate pass rate is consistently high and you can explain every meaningful source, raise policy toquarantine. Many teams ramp withpct=, applying the policy to a fraction of mail first, then widening it. Keep reading the reports: the disposition column now shows failing mail being quarantined, and you confirm in the data that no legitimate source got caught.
- Move to
p=rejectand hold. Once quarantine has run clean and the source list stays stable, raise policy toreject. Spoofed mail is now blocked outright at the receiver, and the disposition on those failing sources readsreject. You are not finished: keep reading the reports, because new senders appear, vendors rotate infrastructure, DKIM keys expire and records drift. The requirements page covers the policy thresholds that Google, Yahoo and Microsoft now expect bulk senders to meet, which for most senders means reaching enforcement rather than parking atp=none.
Alerts: reading the reports for you between visits
Even a perfectly parsed dashboard only helps when someone looks at it, and the changes that matter most happen between visits. The natural endpoint of report analysis is to watch the parsed data continuously and raise an alert the moment something moves, by email, Slack or a webhook into your own systems.
- A pass rate drops. A vendor changed sending infrastructure or a DKIM key expired and your legitimate mail started failing. You hear about it the same day, while it is a minor fix, rather than discovering at month end that a fortnight of invoices bounced.
- A new unauthenticated source appears. A server you have never seen begins sending as your domain and failing authentication. That is either a tool nobody registered or someone spoofing you, and both deserve a look immediately.
- A policy regresses. Someone edits DNS and your
p=rejectquietly becomesp=none, or the record disappears entirely during a migration. Policy drift is common, and an alert catches it before your protection is gone for weeks. The header section of every report, recording the policy each receiver observed, is what makes this detectable.
Each alert links straight back to the source and the rows behind it, so the message is never a vague "something changed" but a specific "this source, this volume, this result, this disposition". That is the difference between data and decisions, and it is the entire job of aggregate report analysis: take the thousands of XML rows arriving every day, reconcile them into source lists, alignment and disposition, and hand you the few facts that tell you what to fix next and when it is safe to enforce.
Start by checking what your domain publishes today with the DMARC checker, decode a single report in the DMARC report analyzer to see the format with your own eyes, then let the analytics product run that analysis across every report and every domain, continuously, so you are reading answers instead of XML.