How to read a DMARC report (with a real example)

Publish a DMARC record with a rua= address and within a day or two the reports start arriving: emails from google.com, outlook.com, yahoo.com with .xml.gz attachments. Each one is a receiver's daily summary of every message it saw claiming to be your domain. Buried in that XML is everything you need to enforce DMARC safely — here's how to read it.

Updated July 13, 2026

The shape of a report

One report = one receiver × one day (usually). It contains metadata (who sent it, the date range), your published policy as they saw it, and then a list of record rows — one per source IP that sent mail as your domain.

<record>
  <row>
    <source_ip>203.0.113.42</source_ip>
    <count>137</count>
    <policy_evaluated>
      <disposition>none</disposition>
      <dkim>pass</dkim>
      <spf>fail</spf>
    </policy_evaluated>
  </row>
  <identifiers>
    <header_from>yourdomain.com</header_from>
  </identifiers>
  <auth_results>
    <dkim><domain>yourdomain.com</domain><result>pass</result></dkim>
    <spf><domain>bounce.esp-mail.com</domain><result>pass</result></spf>
  </auth_results>
</record>
The part that matters: one record row

Read it bottom-up: auth_results is the raw truth (what authenticated, for which domain), policy_evaluated is the DMARC verdict after alignment. In this example SPF passed for the ESP's bounce domain — unaligned, so DMARC's spf shows fail — but DKIM passed aligned, so the message passed DMARC overall. 137 messages, all fine.

The three patterns to look for

  • Legitimate & aligned — known sender IPs, dkim or spf pass in policy_evaluated. Healthy; nothing to do.
  • Legitimate but failing — a service you recognize (or an IP that resolves to one) with neither method aligned. This is your to-do list before enforcing: usually the ESP's custom-domain authentication was never turned on.
  • Spoofing — IPs you can't attribute to any service you use, failing everything, often from unexpected countries. At p=none this mail is being delivered in your name; it's the reason to keep moving toward reject.

Why nobody reads these by hand for long

A domain of any size gets reports from a dozen receivers daily, each covering hundreds of IPs that you have to look up and attribute one by one. That's the entire reason DMARC report analyzers exist. HealthCheck Email receives your reports (the record it generates points rua= at us), parses every attachment automatically, labels each source by name — Google Workspace, SendGrid, Klaviyo — and turns the verdict history into charts, alerts, and an answer to "is it safe to enforce yet?"

Common questions

What's the difference between RUA and RUF reports?+

RUA (aggregate) reports are daily statistical summaries — counts per source IP, no message content. RUF (forensic) reports are per-message failure samples; most large receivers don't send them for privacy reasons. Everything you need for deployment decisions is in RUA.

Why am I getting reports from providers I never email?+

Reports are triggered by mail claiming to be your domain arriving at that receiver — from anyone, anywhere. Reports from unexpected providers often mean forwarding, or someone spoofing you toward their users. That's the system working.

How soon after publishing DMARC do reports arrive?+

Google typically sends the first report within 24 hours, others within a day or two. Low-volume domains may only get occasional reports — no mail seen means no report to send.

Can the rua= address be on a different domain?+

Yes — that's how hosted analyzers work. The analyzer's domain publishes a special verification record authorizing it to receive your reports; compliant receivers check for it automatically. Our onboarding handles this for you.