Back to Learning Hub
EMAIL AUTHENTICATION August 21, 2026 · 9 min read · 1.9K/mo

How to Read a DMARC Report (Aggregate XML Explained)

DMARC aggregate reports tell you exactly who is sending email as your domain, whether they pass authentication, and what action receivers took. Here's how to decode the XML and use it to harden your email setup.

D
DomainScan Team
DomainScan
Share
EMAIL AUTHENTICATION

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

FieldWhat it means
org_nameWho sent this report (e.g., google.com, outlook.com)
report_idUnique ID for this report — use when filing issues with reporters
date_rangeUnix 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.

FieldWhat it means
domainYour domain
adkimDKIM alignment: r = relaxed, s = strict
aspfSPF alignment: r = relaxed, s = strict
pPolicy applied: none, quarantine, or reject
spSubdomain policy
pctPercentage 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

FieldWhat it means
source_ipIP address that sent the email — look this up to identify the sending service
countNumber of messages from this IP during the reporting period
policy_evaluated.dispositionWhat the receiver did: none (delivered), quarantine (spam), reject (blocked)
policy_evaluated.dkimDid DKIM pass with alignment? pass or fail
policy_evaluated.spfDid 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

FieldWhat it means
header_fromThe domain in the From: header — always your domain in legitimate reports
envelope_fromThe 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 RangeProvider
209.85.x.x, 74.125.x.xGoogle Workspace
40.92.x.x, 52.101.x.xMicrosoft 365
149.72.x.x, 167.89.x.xSendGrid
149.20.x.x, 198.37.x.xMailchimp/Mandrill
54.240.x.x, 72.21.x.xAmazon SES

Tools to Avoid Reading Raw XML

Raw XML reports are unreadable at scale. Use a parser:

ToolWhat it doesCost
Google Postmaster ToolsShows domain reputation + auth rates from Gmail’s perspectiveFree
DmarcianFull report parser, source identification, trend chartsFree tier (3 domains)
Valimail MonitorSaaS parser with sender identificationFree tier
Postmark DMARCWeekly email digest summaryFree
parsedmarcSelf-hosted Python tool, exports to Elasticsearch/GrafanaOpen source
mxtoolbox DMARCSimple report viewerFree

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=nonep=quarantinep=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

01

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.

02

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.

03

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.

04

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.

05

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.

#email-authentication#email-auth#dns#domainscan
D
DomainScan Team
Writes about DNS infrastructure, email authentication, domain security, and the engineering behind automated domain intelligence.