Understanding DMARC reports
DMARC aggregate (RUA) reports are the window into your email authentication posture. Here's how to read them and why they're essential for moving toward enforcement.
⚠️ Heads up — this one's deep in the weeds
Everything below is genuinely technical and dry. When we say UglyDMARC takes the ugly out of DMARC, this is exactly the stuff we mean — and the good news: with our reports and dashboards, you'll never need to know any of it. Read on if you're curious; otherwise, see how UglyDMARC does it for you.
What are DMARC RUA reports?
When you publish a DMARC record with rua=mailto:rua@reports.uglydmarc.com, receiving mail servers send you daily aggregate reports (RUA = Reporting URI for Aggregate). These reports summarize:
- How many emails arrived claiming to be from your domain
- How many passed DKIM / SPF / DMARC alignment
- Which source IPs sent them (legitimate and spoofed)
- Which organizations received them (Gmail, Outlook, Yahoo, etc.)
Reports arrive as XML attachments, one per receiving organization per day. You might get reports from 50+ mail providers (Gmail, Outlook, Yahoo, AOL, corporate mail systems, etc.), giving you a comprehensive view of your domain's authentication posture.
Tip
RUA reports are the most valuable data you have for understanding who is sending mail claiming to be from your domain. Without them, you're flying blind. Always enable reporting, even when you're in p=none monitor mode.
DMARC report structure
A DMARC RUA report is an XML file with this structure:
<?xml version="1.0" encoding="UTF-8" ?> <feedback> <report_metadata> <org_name>Google</org_name> <email>noreply-dmarc-support@google.com</email> <report_id>google.com!example.com!1685836800!1685923199</report_id> <date_range><begin>1685836800</begin><end>1685923199</end></date_range> </report_metadata> <policy_published> <domain>example.com</domain> <p>none</p> <aspf>r</aspf> <adkim>r</adkim> </policy_published> <record> <row> <source_ip>192.0.2.1</source_ip> <count>42</count> <policy_evaluated> <disposition>none</disposition> <dkim>pass</dkim> <spf>pass</spf> <dmarc_pass>true</dmarc_pass> </policy_evaluated> </row> </record> </feedback>
Key sections:
<report_metadata>
Who sent the report and when.
org_name— The organization that sent the report (Google, Microsoft, Yahoo, etc.)email— Contact address for the reporting organizationreport_id— Unique ID for this report (format: org!domain!begin_timestamp!end_timestamp)date_range— The 24-hour period this report covers (in Unix timestamps)
<policy_published>
A snapshot of your published DMARC policy at the time the report was generated.
domain— Your domainp— Your DMARC policy (none, quarantine, or reject)aspf— Your SPF alignment mode (r = relaxed, s = strict)adkim— Your DKIM alignment mode (r = relaxed, s = strict)
<record> / <row>
One row per (source IP, authentication result) pair. For example, if 42 emails came from 192.0.2.1 and passed both SPF and DKIM, there's one row for that combination.
source_ip— The IP address that sent the emailcount— How many emails from that IP had this authentication resultpolicy_evaluated— The authentication results and disposition
Reading authentication results
Each row in the report shows the authentication outcomes for a batch of emails from a single source IP:
<dkim> and <spf>
Can be pass, fail, softfail, neutral, none, temperror, or permerror.
pass— The mechanism passed (IP matched SPF, or signature verified for DKIM)fail— The mechanism failed (IP didn't match, or signature didn't verify)softfail— SPF returned ~all (soft fail, not a hard rejection)neutral— No SPF/DKIM policy found for the domainnone— Mechanism was not evaluatedpermerror— The SPF record was malformed or hit the 10-lookup limit
<policy_evaluated> section
<alignment>
Shows alignment results for DKIM and SPF. (Note: not all ISPs report this; it's optional.)
dkim_align—passif DKIM aligned,failotherwisespf_align—passif SPF aligned,failotherwise
<dmarc_pass>
Boolean. true if the email passed DMARC (SPF or DKIM passed AND aligned). false if DMARC failed.
<disposition>
What the receiver did with the email given your policy. Can be none (delivered), quarantine (spam folder), or reject (rejected). Note: this reflects your policy; it doesn't mean the email was actually rejected if your policy was p=none.
Reading an example report
Let's interpret a simple report with three rows:
Row 1: Legitimate mail from Google Workspace
<source_ip>192.0.2.1</source_ip> # example sender IP <count>156</count> # 156 emails from this IP <dkim>pass</dkim> # DKIM signature verified <spf>pass</spf> # SPF check passed <dmarc_pass>true</dmarc_pass> # Email passed DMARC
Interpretation: 156 emails from Google Workspace passed both SPF and DKIM, and alignment held. These are legitimate.
Row 2: Email failing SPF (probably a vendor outside your record)
<source_ip>203.0.113.50</source_ip> # Unknown IP <count>8</count> <dkim>fail</dkim> <spf>fail</spf> # Both failed <dmarc_pass>false</dmarc_pass> # DMARC failed
Interpretation: 8 emails from IP 203.0.113.50 failed both SPF and DKIM. These are likely spoofed or from a vendor not in your SPF record. If this is a legitimate vendor you use, you need to add them to your SPF/DKIM configuration.
Row 3: Email with partial alignment (DKIM passes, SPF fails)
<source_ip>198.51.100.20</source_ip> <count>5</count> <dkim>pass</dkim> <spf>fail</spf> <dmarc_pass>true</dmarc_pass> # DMARC still passed (DKIM alone is enough)
Interpretation: 5 emails passed DKIM but failed SPF. DMARC still passed because only one of SPF or DKIM needs to pass and align. (This often happens when a vendor uses a subdomain for signing but sends from a different IP.)
Common DMARC report patterns
High pass rate (>95%): you're aligned
If most of your mail passes DMARC, you're in good shape. You can confidently move from p=none to p=quarantine, then to p=reject.
Sudden spike in unknown IPs: you're being spoofed
If a new IP suddenly sends 1,000 emails claiming to be from your domain and fails DMARC, you're likely the target of a spoofing attack. DMARC is working—it caught it. Enforce p=reject to stop the attack.
One vendor fails SPF but passes DKIM: subdomain mismatch
A vendor might bounce mail from a different subdomain or IP than their main SPF record covers. The DKIM signature proves they're legitimate, so DMARC still passes (in relaxed mode). No action needed, but you might tighten your SPF if you want stricter control.
Permerror in SPF: you hit the 10-lookup limit
If you see permerror in the SPF column, your SPF record exceeded the 10-lookup limit. This is a critical issue—emails from authorized servers are failing. You need to solve the lookup problem (either by flattening or using synthetic SPF like UglyDMARC).
Why parsing raw DMARC XML is painful
DMARC reports are powerful but tedious to parse manually:
- Multiple files: You get 50+ XML files per day (one from each mail provider). Aggregating them is tedious.
- Time zones and timestamps: Reports use Unix timestamps. Figuring out which report covers which day requires conversion.
- Vendor variations: Different mail providers include different fields (some omit alignment info, some include forensic data). Your parsing logic gets complex.
- Duplicate filtering: If a mail server retries sending a report, you might get duplicates. Deduplication requires custom logic.
- Trend analysis: Comparing week-over-week pass rates or spotting new threats requires aggregation and visualization. Raw XML gives you none of this.
- False positives: Some vendors send malformed XML. Parsing requires robust error handling.
Warning
Attempting to parse DMARC reports manually with regex or simple XML parsing often leads to missed data, incorrect conclusions, and wasted time. A proper dashboard tool is essential.
The better approach: dashboards and automation
Instead of parsing XML manually, use a tool (like UglyDMARC) to:
- Ingest reports automatically: Tools collect reports from your email inbox and parse them automatically.
- Aggregate across domains: If you manage multiple domains, see a unified dashboard showing pass rates, failures, and threats across all of them.
- Visualize trends: Charts and graphs showing DMARC pass rates over time, helping you make informed decisions about policy changes.
- Alert on threats: Automatic notifications when spoofing spikes, permerrors appear, or new senders emerge.
- Search and filter: Find emails from a specific IP, organization, or date range without writing parsing code.
- Export for compliance: Generate CSVs and reports for security audits, compliance frameworks, and stakeholder reviews.
A good dashboard replaces hours of manual parsing with minutes of insight.
Going further
DMARC reports are the foundation of a strong authentication posture. Combined with SPF (and solving the 10-lookup limit) and DKIM, they give you the visibility and control to confidently enforce p=reject and eliminate impersonation attacks.
Ready to get started? Sign up for UglyDMARC to ingest your DMARC reports, get instant dashboards, and move safely from monitoring to enforcement.