DMARC reports: how to read the aggregate XML receivers send you
A day or two after you publish a DMARC record with a
rua address, the first report arrives: an email from
noreply-dmarc-support@google.com with a .xml.gz attachment and a
subject line of pure machine syntax. Unzip it and you're looking at a
few hundred lines of XML — the receiving side of the email system
telling you, in its own format, everything it saw sent under your
domain's name yesterday.
Most people close the file and never open another one. That's the
canonical failed DMARC deployment: reports piling up unread while the
policy sits at p=none forever. This guide is the reading lane of our
DMARC series — what the reports contain, element by element, and the
questions to interrogate them with. Setup lives in its own
walkthrough, policy strategy in
another, and per-message failure diagnosis in a
third.
Two report types, one of which matters
DMARC defines two reporting channels. Aggregate reports (rua=)
are statistical summaries — no message content, just counts of which
IPs sent mail as your domain and how authentication went — sent by
each receiver on a regular cycle, typically every 24 hours. Forensic
or failure reports (ruf=) were meant to be per-message copies of
individual failures, but most large receivers stopped sending them
years ago over privacy concerns.
Practical consequence: build your monitoring entirely on aggregate
reports, and don't add a ruf= tag expecting a stream that mostly
won't come. Everything below is about the rua XML.
Who sends them, and when
Any receiver that processes meaningful volume from you and honors DMARC reporting will send reports: Google, Microsoft, Yahoo, and a long tail of providers and security gateways. Each reports independently on its own cycle, so a normal morning brings several files covering the same day from different vantage points. Volume scales with your sending spread — a sender with global traffic can receive dozens of files a day, which is the point at which parsing tooling stops being optional.
Reports are delayed and periodic — a summary of a completed window, usually yesterday. They are a trend instrument, not an alarm system; nothing in the DMARC reporting design tells you about a failure within minutes.
Anatomy of the XML
A minimal but realistic aggregate report, trimmed to the parts that matter:
<feedback>
<report_metadata>
<org_name>google.com</org_name>
<date_range><begin>1755648000</begin><end>1755734400</end></date_range>
</report_metadata>
<policy_published>
<domain>example.com</domain>
<p>none</p> <sp>none</sp> <adkim>r</adkim> <aspf>r</aspf> <pct>100</pct>
</policy_published>
<record>
<row>
<source_ip>203.0.113.25</source_ip>
<count>1284</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>fail</spf>
</policy_evaluated>
</row>
<identifiers><header_from>example.com</header_from></identifiers>
<auth_results>
<dkim><domain>example.com</domain><selector>s1</selector><result>pass</result></dkim>
<spf><domain>mailer.espmail.net</domain><result>pass</result></spf>
</auth_results>
</record>
</feedback>
Four blocks, four jobs:
report_metadata— who's reporting and the time window (Unix timestamps; that pair is one day).policy_published— your DMARC record as the receiver read it. If this doesn't match what you think you published, stop and check the live record with the DMARC checker before interpreting anything else.record/row— the payload. One row per source IP (per authentication outcome): the IP, how many messages, and the DMARC evaluation.auth_resultsvspolicy_evaluated— the pair that confuses everyone, and the key to reading reports correctly. See next section.
The distinction the whole format hinges on
auth_results reports the raw outcomes: which domains passed
SPF and DKIM, regardless of
alignment. policy_evaluated reports the DMARC-relevant outcomes:
pass only if the mechanism passed and aligned with your From
domain.
Read the sample with that lens. Raw SPF passed — but for
mailer.espmail.net, the ESP's bounce domain, so evaluated SPF is
fail (no alignment). Raw DKIM passed for example.com itself, so
evaluated DKIM is pass. One aligned pass is enough: DMARC passed for
all 1,284 messages in the row. That signature — raw pass, evaluated
fail on SPF, carried by aligned DKIM — is the normal, healthy pattern
for ESP-sent mail, not a problem to fix.
What disposition none means
<disposition> records what the receiver did with failing mail:
none (delivered normally), quarantine, or reject.
The value everyone searches for — disposition: none — almost always
means exactly what you'd hope: your policy is p=none, so the
receiver applied no sanction. On a row where DMARC passed, disposition
is none by definition regardless of policy — there was nothing to
sanction. The combination worth attention is different: policy at
quarantine or reject with failing rows still showing
disposition: none means the receiver overrode your policy
(reports may carry a policy_override reason — forwarding, mailing
list, local exception). Occasional overrides are normal receiver
discretion; wholesale ones are worth investigating.
Reading a report like an operator
Three questions turn XML into decisions:
1. What sends as my domain? Collect source IPs across a few weeks of reports, resolve them (reverse DNS gets you far — the reverse DNS checker does one-offs), and sort into: my known platforms, my forgotten systems, forwarders, and strangers. The forgotten-systems column is where DMARC earns its keep — the CRM someone connected in 2021, the regional office's relay.
2. Is my legitimate mail aligned? For every source you claim, the evaluated results should show at least one aligned pass. A claimed source failing both is a work item with a name on it — usually the ESP's custom-domain signing left unfinished. Per-message diagnosis of any surprise lives in the failure guide.
3. What's the failure floor? The stranger rows — unrecognized IPs
failing everything — are spoofing pressure. You don't fix them; you
note their existence as the argument for finishing the ratchet to
enforcement, and after moving policy you watch their dispositions flip
to quarantine or reject.
Track the trend of aligned-pass percentage over weeks. When it holds steady at effectively-all of your legitimate volume, you've met the gate for tightening policy.
Hand-reading vs tooling
At low volume, hand-reading is genuinely fine: a text editor, the four-block map above, twenty minutes a week. The XML was designed to be machine-parsed though, and once reports arrive faster than patience — multiple domains, dozens of files daily — a parsing service (several offer free tiers for modest volume) that aggregates rows into per-source dashboards is the sane move. We don't score or rank those services; any of them beats unread gzip files. The failure mode to avoid isn't manual processing — it's no processing.
Whichever route, keep the raw habit: when a dashboard says something
surprising, open the underlying XML for the affected window and check
the auth_results yourself. Summaries compress; the rows are the
evidence.
Related guides
- DMARC checker — confirm the live record
matches
policy_published - DMARC generator — fix the record when the reports reveal it's wrong
- Email header analyzer — the per-message view that complements aggregate rows
- Reverse DNS checker — identify report source IPs
- What is DMARC? — alignment and tag reference
- DKIM — the aligned-pass workhorse in most reports
- How to set up DMARC — publishing the record that starts the stream
About this guide
Written by InboxRatio Editorial. The report anatomy follows RFC 7489's aggregate schema; reading patterns reflect our own operation of DMARC reporting on the test domains behind our benchmark. We name no report-parsing vendor as a recommendation — the workflow above works with any of them, or none.
Methodology
InboxRatio runs authenticated sending domains for its controlled placement tests, and DMARC aggregate reports are part of how we verify our own authentication stays healthy between cycles. Our benchmark — identical campaigns through each platform to a fixed seed list, placement recorded per provider — is documented at how we test.
Last updated
21 August 2026. Format details and receiver reporting behavior reviewed quarterly.
Frequently asked questions
What is a DMARC report?
A statistical summary a receiving provider sends to your record's
rua address, typically daily: which IPs sent mail claiming your
domain, message counts, SPF/DKIM outcomes with alignment, and what
the receiver did with failures. No message content is included.
Why am I getting DMARC report emails?
Your domain (or a domain listing your address as its rua target)
publishes a DMARC record requesting them. They're a feature, not
spam — though if you never published a record, check who did, and
whether your address was listed with permission.
What does disposition none mean in a DMARC report?
The receiver applied no sanction: either your policy is p=none, or
the row's messages passed DMARC and there was nothing to act on. It
only signals a problem when failing rows show none under a
quarantine/reject policy — that's a receiver override, usually
explained by a policy_override reason.
Why does SPF show fail in my reports when my SPF record is fine?
You're likely reading policy_evaluated, which reports aligned SPF.
ESP mail routinely passes raw SPF for the platform's bounce domain —
unaligned with your From domain, hence "fail" — while aligned DKIM
carries the DMARC pass. Check auth_results for the raw outcome
before concluding anything is broken.
How often do DMARC reports arrive? Most large receivers send one report per domain per day, covering the previous 24-hour window. Reporting is receiver-initiated: providers that saw no mail from your domain send nothing, and a handful of smaller receivers don't report at all.
Do I need a DMARC report analyzer tool? Need — no; the XML is hand-readable at low volume with the map in this guide. Want — probably, once daily files multiply. The non-negotiable part is that someone reads the data on a schedule, whatever the tooling.
Reports only pay when interrogated — put a recurring slot on the calendar, ask the three operator questions, and gate your policy ratchet on what the rows show. Before the next report arrives, confirm the record it will describe is the one you meant to publish: thirty seconds with the DMARC checker.