DMARC aggregate reports are the audit trail of your email sending. Every day, receivers like Gmail and Outlook email you XML files showing every source that sent mail using your domain, whether each passed SPF and DKIM, and what action the receiver took. Most domains collect these reports for months without reading them — which defeats the purpose of DMARC entirely.
Where Reports Come From
When you publish a DMARC record with rua=mailto:[email protected], receiving mail servers send you daily reports. Each report covers one 24-hour period and one reporting organization. A domain sending significant volume can receive dozens of reports daily — one from Google, one from Microsoft, one from Yahoo, and so on.
Reports arrive as .xml.gz or .xml.zip attachments with filenames like:
google.com!example.com!1690243200!1690329600.xml.gz
The filename format: reporter!yourdomain!start-epoch!end-epoch
Raw XML Structure
A raw DMARC aggregate report looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<feedback>
<report_metadata>
<org_name>google.com</org_name>
<email>[email protected]</email>
<report_id>12345678901234567890</report_id>
<date_range>
<begin>1690243200</begin>
<end>1690329600</end>
</date_range>
</report_metadata>
<policy_published>
<domain>example.com</domain>
<adkim>r</adkim>
<aspf>r</aspf>
<p>reject</p>
<sp>reject</sp>
<pct>100</pct>
</policy_published>
<record>
<row>
<source_ip>209.85.220.41</source_ip>
<count>1523</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>example.com</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>example.com</domain>
<selector>google</selector>
<result>pass</result>
</dkim>
<spf>
<domain>example.com</domain>
<result>pass</result>
</spf>
</auth_results>
</record>
</feedback>
Decoding Every Section
report_metadata
| Field | What it means |
|---|---|
org_name | Who sent this report (e.g., google.com, outlook.com) |
report_id | Unique ID for this report — use when filing issues with reporters |
date_range | Unix timestamps for the reporting period (convert at epochconverter.com) |
policy_published
This is the DMARC policy the reporter read from your DNS during the reporting period. If you changed your policy and this shows the old one, reports from before the change will reflect the old policy.
| Field | What it means |
|---|---|
domain | Your domain |
adkim | DKIM alignment: r = relaxed, s = strict |
aspf | SPF alignment: r = relaxed, s = strict |
p | Policy applied: none, quarantine, or reject |
sp | Subdomain policy |
pct | Percentage of messages the policy was applied to |
record — The Core Data
Each <record> represents a unique combination of source IP + authentication results. One report can have dozens of records.
row
| Field | What it means |
|---|---|
source_ip | IP address that sent the email — look this up to identify the sending service |
count | Number of messages from this IP during the reporting period |
policy_evaluated.disposition | What the receiver did: none (delivered), quarantine (spam), reject (blocked) |
policy_evaluated.dkim | Did DKIM pass with alignment? pass or fail |
policy_evaluated.spf | Did SPF pass with alignment? pass or fail |
Alignment is the key concept. policy_evaluated.dkim=pass means DKIM passed AND the d= domain aligned with the From: domain. A raw DKIM pass without alignment doesn’t satisfy DMARC.
identifiers
| Field | What it means |
|---|---|
header_from | The domain in the From: header — always your domain in legitimate reports |
envelope_from | The Return-Path/MAIL FROM domain — may differ from header_from |
auth_results
The raw authentication results before DMARC alignment evaluation:
<dkim>
<domain>example.com</domain> <!-- signing domain -->
<selector>google</selector> <!-- DKIM selector used -->
<result>pass</result> <!-- raw DKIM result -->
</dkim>
<spf>
<domain>example.com</domain> <!-- envelope sender domain -->
<result>pass</result> <!-- raw SPF result -->
</spf>
A record can show auth_results.spf=pass but policy_evaluated.spf=fail — this means SPF passed on a different domain than your From: domain (common with third-party senders using their own Return-Path).
Reading Records: What to Look For
Healthy Record (Your Primary Sender)
source_ip: 209.85.220.41 → Google's outbound mail server
count: 1,523
disposition: none → delivered normally
dkim: pass → DKIM aligned
spf: pass → SPF aligned
This is Google Workspace sending your email. Everything passes. Nothing to do.
DMARC Failure — Third-Party Sender
source_ip: 167.89.3.50 → SendGrid IP
count: 438
disposition: none (policy=none) → not blocked yet because p=none
dkim: fail → no DKIM alignment
spf: fail → SPF passes on sendgrid.net, not your domain
This means you’re sending through SendGrid but haven’t configured DKIM signing for your domain in their platform. At p=none these are delivered. At p=reject they’d be blocked. Fix before moving to a stricter policy: add your domain’s DKIM key in SendGrid’s domain authentication settings.
Forwarder / Mailing List
source_ip: 198.51.100.20 → a mailing list server
count: 12
disposition: none
dkim: fail → list broke the signature by modifying subject/footer
spf: fail → forwarded from different envelope
Mailing lists and forwarders often break DMARC because they modify messages. This is expected and hard to fix from your side. ARC (Authenticated Received Chain) is the long-term solution — many major receivers now support it.
Unauthorized Sender / Phishing Attempt
source_ip: 185.220.101.5 → Tor exit node / unknown
count: 3
disposition: reject → blocked (only if p=reject)
dkim: fail
spf: fail
Someone trying to spoof your domain. At p=reject this was blocked. At p=none it was delivered. This is exactly why moving to p=reject matters.
Identifying Source IPs
To identify an unknown source_ip:
# Reverse DNS lookup
dig -x 209.85.220.41 +short
# → mail-wm1-f41.google.com
# WHOIS
whois 209.85.220.41 | grep -i "org\|netname\|descr"
Common IP ranges by service:
| IP Range | Provider |
|---|---|
| 209.85.x.x, 74.125.x.x | Google Workspace |
| 40.92.x.x, 52.101.x.x | Microsoft 365 |
| 149.72.x.x, 167.89.x.x | SendGrid |
| 149.20.x.x, 198.37.x.x | Mailchimp/Mandrill |
| 54.240.x.x, 72.21.x.x | Amazon SES |
Tools to Avoid Reading Raw XML
Raw XML reports are unreadable at scale. Use a parser:
| Tool | What it does | Cost |
|---|---|---|
| Google Postmaster Tools | Shows domain reputation + auth rates from Gmail’s perspective | Free |
| Dmarcian | Full report parser, source identification, trend charts | Free tier (3 domains) |
| Valimail Monitor | SaaS parser with sender identification | Free tier |
| Postmark DMARC | Weekly email digest summary | Free |
| parsedmarc | Self-hosted Python tool, exports to Elasticsearch/Grafana | Open source |
| mxtoolbox DMARC | Simple report viewer | Free |
For most domains, Dmarcian free tier or Postmark DMARC covers the basics during the monitoring phase.
Acting on Report Data
Work through this checklist when reviewing reports:
1. Find all failing sources
Filter records where policy_evaluated.dkim=fail AND policy_evaluated.spf=fail. These are DMARC failures.
2. Identify each source IP Is it a service you use? A forwarding list? An unknown IP?
3. Fix known failing sources before escalating policy For each legitimate service that’s failing:
- Enable DKIM signing for your domain in that service’s settings
- Or add their sending IPs to your SPF record (for SPF alignment)
4. Check for unknown senders Any IP you don’t recognize sending significant volume is either unauthorized use or a sending service you forgot. Investigate.
5. Monitor disposition
If disposition=quarantine or reject for messages with count > 0 and the source looks legitimate, you have a misconfigured sender that’s being blocked. Fix before moving to stricter policy.
6. Move policy when reports are clean
When reports show consistent pass for all your legitimate sending sources and none for unknown sources only, you’re ready to move from p=none → p=quarantine → p=reject.
Sample Review Workflow
Weekly review (during p=none phase):
1. Open report in Dmarcian or similar
2. Filter: disposition = quarantine/reject → investigate each
3. Filter: dkim=fail OR spf=fail → list unknown source IPs
4. Reverse-lookup each unknown IP
5. For known services: fix authentication configuration
6. For unknown IPs: note — these are blocked at p=reject
7. If 0 legitimate sources failing → ready to move to p=quarantine
DMARC reports are the feedback loop. Publishing the record starts the monitoring. Reading the reports is how you learn what to fix. Most failed DMARC deployments fail because the reports were collected and ignored, not because the technology is hard.
Common Questions
How do I get DMARC reports sent to me?
Add an rua= tag to your DMARC DNS record pointing to an email address you control: v=DMARC1; p=none; rua=mailto:[email protected]. Within 24 hours of publishing this, large receivers (Gmail, Outlook, Yahoo) will start emailing you daily XML reports. Make sure the target email address exists and can receive mail. If you want reports sent to a third-party service's address, you also need to publish a permission record at yourdomain.com._report._dmarc.theirservice.com.
I'm not getting any DMARC reports. Why?
Four causes: (1) No rua= tag in your DMARC record — check with: dig TXT _dmarc.yourdomain.com. (2) No email sent from your domain yet — receivers only report on traffic they've seen. (3) Your rua mailbox is rejecting the reports — test it manually. (4) You're sending very low volume — some receivers only send reports if they've seen enough traffic from your domain. Google sends reports for any volume; Outlook has a minimum threshold.
What's the difference between rua and ruf reports?
rua= (aggregate) reports are daily summaries showing message counts, source IPs, and pass/fail results in aggregate. They contain no email content. ruf= (forensic/failure) reports are near-real-time messages sent when individual emails fail — they may contain message headers and sometimes body excerpts. Most organizations use rua only: it gives full visibility without privacy exposure. ruf reports are rarely sent by major providers (Google and Outlook have largely stopped sending them) and some privacy regulations restrict using them.
Which senders send DMARC reports?
All major consumer and business email providers: Gmail, Outlook/Hotmail/Office365, Yahoo/AOL, Apple iCloud, Proton Mail, Zoho, and many ISPs. Enterprise mail gateways (Barracuda, Mimecast, Proofpoint) also send reports when handling inbound email. The more mail your domain receives, the more report sources you'll see. Small domains may only get reports from Gmail and Outlook.
My report shows pass for everything. Am I done?
Not necessarily. All-pass reports during p=none monitoring mean your known sending sources are configured correctly — but they don't tell you about sources you don't know about. Check for unexpected source IPs: if you only use Google Workspace but the report shows a SendGrid IP with 200 pass messages, someone else has your domain in their SPF or is using it without authorization. Investigate every source IP, not just the failing ones.