Reading DMARC aggregate reports and rolling out to p=reject safely
DMARC aggregate reports tell you, per sending source, how much mail passed or failed SPF and DKIM alignment — the only reliable way to know whether moving your policy to quarantine or reject will block legitimate mail or just spam. This guide walks through reading a report and a staged rollout that won't break your own mail.
By AdminKit team, Netbase JSC · Updated October 22, 2026
Why aggregate reports exist
RFC 7489 built reporting into DMARC from the start, because a domain owner publishing a policy has no visibility into who’s actually sending mail as their domain without it. The rua tag in a DMARC record tells receivers where to send a daily XML summary: how much mail from each source passed or failed SPF and DKIM alignment, and what policy was applied to it. Without these reports, moving straight to a stricter policy is a guess; with them, it’s a decision based on actual sending data.
_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:[email protected]; fo=1"
ruf (forensic) reports are the other reporting mechanism DMARC defines, sending more detailed per-message failure data closer to real time — but as dmarc.org’s overview notes, DMARC’s value comes from the aggregate feedback loop between senders and receivers, and in practice most large mailbox providers only support rua, not ruf, due to the privacy sensitivity of sharing message-level detail. Plan a rollout around aggregate reports; treat forensic reports as a bonus if any receiver sends them.
Reading an aggregate report
Aggregate reports arrive as gzipped XML attachments, one per reporting receiver per day. The structure that matters for rollout decisions:
<record>
<row>
<source_ip>192.0.2.44</source_ip>
<count>1540</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>fail</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>example.com</header_from>
</identifiers>
</record>
This one block says: 1,540 messages claiming to be from example.com arrived from 192.0.2.44, passed DKIM but failed SPF, and (since the policy is currently none) nothing was done about it. The question to ask for every source_ip in every report: is this one of my legitimate sending services, or not? A legitimate marketing or support tool that’s DKIM-passing but SPF-failing usually just needs an SPF include: added; a source you don’t recognize failing both checks is a candidate for genuine spoofing, which is exactly what a stricter policy is meant to block.
Reading raw XML by hand across several reports a day doesn’t scale past a handful of domains — most teams use a DMARC report parser or their mailbox provider’s dashboard to aggregate the data instead of opening each file manually, but the underlying fields above are what any such tool is summarizing.
A staged rollout that won’t break your mail
- Start at
p=none. This mode only collects data — mail isn’t quarantined or rejected regardless of what passes or fails. There’s no downside to turning this on immediately once you have anruaaddress you’ll actually monitor. - Review reports for every legitimate source. Check daily or weekly rather than waiting until the end of the window, so you’re not surprised by an infrequent sender (an annual tax-form mailer, a one-off marketing campaign) that only shows up once.
- Fix each failing legitimate source. Usually a missing SPF
include:or a sending service that isn’t DKIM-signing its mail at all. Re-check with DMARC check and MX lookup after each fix. - Move to
p=quarantineat a lowpct, such aspct=10, once reports show only recognized sources failing. This routes a small fraction of still-failing mail to spam rather than committing fully, giving you one more safety check before expanding it. - Raise
pcttoward 100, then switch top=rejectonce aggregate reports consistently show zero unexplained failures from legitimate sources across at least one full reporting cycle.
Skipping straight to p=reject without this review is the single most common way a DMARC rollout causes legitimate mail to silently disappear — rejected mail doesn’t bounce to a sender in a way most people notice, it just never arrives.
Keep monitoring after reject
Aggregate reports don’t stop mattering once you reach p=reject — sending infrastructure changes over time (a new marketing tool, a migrated mail platform), and a newly added legitimate sender that isn’t authorized will simply fail silently under a reject policy unless someone is still watching the reports. Treat the rua address as a standing operational responsibility, not a one-time rollout step.
This guide is general information, not a security audit of your specific network — see our disclaimer for what AdminKit's guidance does and does not commit to.
Frequently asked questions
What's the difference between rua and ruf reports?
`rua` (aggregate reports) are daily XML summaries of pass/fail counts grouped by sending source — the main tool for rollout decisions. `ruf` (forensic reports) are per-message failure reports sent close to real time, but most large receivers (Gmail, Microsoft) don't send them at all due to the privacy implications of sharing message-level data, so don't rely on ruf for rollout decisions.
How long should I stay at p=none before moving to quarantine?
Long enough to see every legitimate sending source at least once, including ones that don't send daily — payroll providers, annual-report tools, or seasonal marketing platforms. Two to four weeks is a reasonable minimum for a typical business, but a domain with infrequent senders may need longer.
A report shows a failing source I don't recognize — what do I do?
Identify it first: the report's `source_ip` and `header_from` fields, cross-referenced with your own list of approved sending services, usually reveal whether it's a forgotten legitimate sender or genuine spoofing. If you can't identify it and it's failing both SPF and DKIM, it's very likely not you — which is exactly what DMARC enforcement is meant to stop.
Can I go straight from p=none to p=reject?
You can, but it's risky — RFC 7489 doesn't require a staged rollout, but skipping quarantine means any sender you failed to identify in the aggregate reports gets outright rejected instead of just flagged, with no safety net. The `pct` tag lets you apply a new policy to only a percentage of mail first, which is the safer way to test reject before committing fully.
Do aggregate reports include message content?
No. Aggregate reports contain only metadata — source IP, volume, pass/fail counts, and policy applied — not subject lines or message bodies, which is part of why most receivers are willing to send them while fewer send the more detailed forensic (ruf) reports.
Related tools
Want AdminKit to watch this for you?
Free checks tell you the state today. Protective DNS and monitoring tell you when it changes.