InboxRatio

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_results vs policy_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

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.