DMARC Reports Explained: How to Read the XML Data and Act on What It Tells You

DMARC generates reports — but most people who implement DMARC never actually read them. The XML files land in your inbox (or a dedicated address), get glanced at once, and then ignored. That's a mistake. DMARC reports contain the single best picture available of who is sending email using your domain, which emails are passing authentication, and which ones might indicate a spoofing attempt.
This guide explains what DMARC reports contain, how to make sense of the XML data, and what to actually do with what you find.
The Two Types of DMARC Reports
DMARC generates two types of reports, configured separately in your DMARC record:
- Aggregate reports (RUA): Sent once per day by each receiving server that processes your email. They summarize all messages received from your domain over the previous 24 hours — how many passed SPF, how many passed DKIM, what IP addresses sent them, and what action the receiving server took.
- Forensic reports (RUF): Sent per-message when an email fails DMARC. These contain much more detail, including portions of the original message. Many providers don't send these for privacy reasons, and they're less commonly used.
The most useful reports for ongoing monitoring are aggregate reports. You should have an RUA address configured in your DMARC record from day one.
Reading the XML: What Each Section Means
Aggregate reports are delivered as XML files, compressed in .zip or .gz format. Here's the basic structure:
<feedback>
<report_metadata>
<org_name>Google Inc.</org_name>
<date_range>
<begin>1718668800</begin>
<end>1718755200</end>
</date_range>
</report_metadata>
<policy_published>
<domain>example.com</domain>
<p>reject</p>
<pct>100</pct>
</policy_published>
<record>
<row>
<source_ip>198.51.100.42</source_ip>
<count>2400</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
</record>
</feedback>
report_metadata
Who sent the report and when. The org_name tells you which mail provider generated it (Google, Microsoft, Yahoo, etc.). The date range is in Unix timestamp format — convert it to confirm you're looking at the right day.
policy_published
This shows the DMARC policy the receiving server read from your DNS record at the time. Check that p (the policy for your domain) matches what you intended to publish. If it doesn't, your DNS hasn't propagated yet or you have an error in your record.
record / row
Each record is a group of messages from a specific source IP with consistent authentication results. Key fields:
source_ip— The IP address that sent the emailcount— How many messages were sent from that IP during the reporting perioddisposition— What the receiving server actually did: none = delivered, quarantine = filtered, reject = bounceddkim— Whether DKIM passed or failedspf— Whether SPF passed or failed
The Patterns That Actually Matter
Reading raw XML is tedious. A DMARC reporting tool parses these files into dashboards. But even in raw XML, here's what to look for:
Unfamiliar IP addresses sending from your domain
If you see source IPs you don't recognize, someone is either spoofing your domain or you have a sending service you forgot to authenticate. Look up unfamiliar IPs to identify the organization behind them.
High failure rates from known services
If your ESP or CRM shows up with high SPF or DKIM failure rates, there's a configuration problem. Common causes: the service is sending from your domain but isn't in your SPF record, or DKIM is enabled in their dashboard but the DNS record was never published correctly.
Disposition mismatches
If your policy is reject but the disposition shows none, the receiving server is overriding your policy — usually because you haven't established enough sender reputation for them to trust enforcement. This is normal when starting out and typically resolves over time.
Moving From Monitor to Enforce
Most guides tell you to start with p=none (monitor mode) and move to quarantine then reject. The DMARC reports are exactly how you decide when it's safe to advance.
The signal to move from none to quarantine: your reports show that all legitimate sending sources — your ESP, CRM, transactional email service, help desk tool — are consistently passing both SPF and DKIM. There should be no unexplained failures from IPs you control.
The signal to move from quarantine to reject: two to four weeks of clean reports after moving to quarantine, with no legitimate mail being caught.
Where to Send Your Reports
Your DMARC record should include an rua tag pointing to an email address that receives reports:
v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com
You can use a dedicated mailbox, or a service that parses them automatically. If you're sending significant volume, you'll receive reports from dozens of providers — processing them manually doesn't scale. Use an aggregation service from day one.
For teams setting up DMARC from scratch, MailDog's DNS and security tools cover DMARC configuration alongside SPF and DKIM. Full documentation is available at maildog.io/docs.
A Quick Monitoring Checklist
- RUA address is configured and receiving reports
- Policy published in reports matches what you intended
- All legitimate sending IPs are identified and authenticated
- No unexplained source IPs with significant volume
- DKIM and SPF are both passing for your main sending sources
- Disposition matches your published policy
DMARC without reading the reports is like installing a security camera and never checking the footage. The data is there — and it tells you things your logs never will. For a broader look at authentication and deliverability practices on the MailDog blog, or to get started with a managed email setup, explore the MailDog mail service.


