DMARC aggregate reports look intimidating the first time you open one. Nested XML elements, Unix timestamps, IP addresses, and cryptic result codes — it reads like a debug log. This guide walks through every element, explains what it means in plain English, and shows you what to look for when diagnosing email authentication problems.
The Top-Level Structure
Every DMARC aggregate report follows the RFC 7489 schema. The root element is always <feedback>, and it contains exactly three types of children:
<report_metadata>— information about the report itself<policy_published>— your DMARC policy as seen by the reporter<record>— one entry per unique sending source (one or more)
<?xml version="1.0" encoding="UTF-8" ?> <feedback> <report_metadata> ... </report_metadata> <policy_published> ... </policy_published> <record> ... </record> <record> ... </record> <!-- potentially thousands more records --> </feedback>
report_metadata: Who Sent This Report
<report_metadata>
<org_name>Google LLC</org_name>
<email>noreply-dmarc-support@google.com</email>
<extra_contact_info>https://support.google.com/a/answer/2466580</extra_contact_info>
<report_id>12456789012345678</report_id>
<date_range>
<begin>1751241600</begin>
<end>1751327999</end>
</date_range>
</report_metadata>org_name
The name of the organization that generated this report. For Google Workspace and Gmail, this is “Google LLC”. For Microsoft (Outlook.com / Office 365), it is “Microsoft Corporation”. Smaller providers may use their company name or their mail server hostname.
The email address of the reporting organization. This is for reference only — do not reply to it. DMARC reporting is one-way.
report_id
A unique identifier for this report, assigned by the sending organization. Useful if you need to correlate a specific report with a provider when troubleshooting.
date_range / begin / end
Unix timestamps (seconds since January 1, 1970 UTC) indicating the start and end of the reporting period. DMARC reports cover a 24-hour window, typically midnight-to-midnight UTC.
new Date(1751241600 * 1000).toISOString() in your browser console, or use an online converter.policy_published: Your DMARC Policy
<policy_published> <domain>example.com</domain> <adkim>r</adkim> <aspf>r</aspf> <p>reject</p> <sp>reject</sp> <pct>100</pct> </policy_published>
domain
The domain this DMARC policy applies to. This is the organizational domain, not necessarily the exact sending domain.
adkim — DKIM alignment mode
r = relaxed (subdomain of the organizational domain qualifies)s = strict (exact domain match required)
Most organizations use r (relaxed). Strict mode is used when you need to prevent subdomains from satisfying alignment for the parent domain.
aspf — SPF alignment mode
Same as adkim but for SPF. r is relaxed, s is strict.
p — policy
The main DMARC policy applied to the organizational domain:
none— deliver and report, no action taken on failuresquarantine— send failures to spam/junk folderreject— reject failures at the SMTP layer
sp — subdomain policy
Policy applied to subdomains of your organizational domain. If absent, the main policy p applies to subdomains as well. Common to set sp=reject even while p=none to immediately protect subdomains from spoofing.
pct — percentage
The percentage of messages that the policy is applied to. Ranges from 1 to 100. Using pct=10 means the policy applies to a random 10% of failing messages — useful for gradual rollout. When not specified, defaults to 100.
record: The Core Data
Each <record> element represents a unique combination of source IP address and authentication outcomes. A report can contain one record or thousands.
<record>
<row>
<source_ip>209.85.128.0</source_ip>
<count>4821</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
<identifiers>
<envelope_to>example.com</envelope_to>
<envelope_from>bounce.example.com</envelope_from>
<header_from>example.com</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>example.com</domain>
<selector>google</selector>
<result>pass</result>
</dkim>
<spf>
<domain>bounce.example.com</domain>
<result>pass</result>
</spf>
</auth_results>
</record>row / source_ip
The IP address of the server that connected to the receiving mail server (the MTA that did the actual SMTP delivery). This is typically the IP of your ESP, your own mail server, or a legitimate/illegitimate third party.
row / count
How many messages were sent from this source IP with this exact combination of authentication outcomes during the reporting period. A count of 4821 means 4,821 messages from that IP, all with the same policy_evaluated result.
policy_evaluated / disposition
What the receiving server actually did with these messages based on your policy:
none— delivered normallyquarantine— placed in spam/junkreject— rejected at SMTP layer (not delivered)
When your policy is p=none, the disposition will always be none regardless of authentication results — the provider is reporting without taking action.
policy_evaluated / dkim and spf
These are the critical fields. They indicate whether DKIM/SPF passed AND aligned. This is different from the raw authentication result in auth_results:
| auth_results result | Alignment | policy_evaluated result |
|---|---|---|
| pass | Domain aligns with From: | pass |
| pass | Domain does NOT align with From: | fail |
| fail | N/A | fail |
A message passes DMARC if at least one of policy_evaluated/dkim or policy_evaluated/spf is “pass”.
identifiers / header_from
The domain in the visible From: header of the email — the domain your recipients see in their mail client. This is the domain that DMARC alignment is checked against.
auth_results / dkim
The raw DKIM check result, before alignment is applied:
pass— signature verified successfullyfail— signature verification failed (key mismatch, body modified)temperror— temporary DNS lookup failure, try again laterpermerror— permanent error (malformed key record, invalid signature)neutral— no result (domain not in DNS)
The selector field identifies which DKIM key was used (e.g.,google, s1, default). If you see a selector you don't recognize, a third-party platform may be signing your messages with its own key.
auth_results / spf
The raw SPF check result for the envelope sender domain (Return-Path):
pass— sending IP is listed in the SPF recordfail— sending IP is explicitly unauthorized (-all)softfail— sending IP is weakly unauthorized (~all)neutral— policy does not make an assertion (?all)none— no SPF record foundtemperror/permerror— DNS errors
Common Record Patterns and What They Mean
Pattern: Both pass — healthy
<policy_evaluated> <disposition>none</disposition> <dkim>pass</dkim> <spf>pass</spf> </policy_evaluated>
This is what you want. The source IP is a known, authenticated sender with correct alignment. All is well.
Pattern: SPF pass, DKIM fail — common for third-party senders
<policy_evaluated> <disposition>none</disposition> <dkim>fail</dkim> <spf>pass</spf> </policy_evaluated>
The sender is in your SPF record and SPF aligns. But DKIM is absent or not aligned. This is passing DMARC via SPF but is fragile — if the message is forwarded, SPF will break. Configure DKIM signing on this platform.
Pattern: Both fail — unauthenticated sender
<policy_evaluated> <disposition>reject</disposition> <dkim>fail</dkim> <spf>fail</spf> </policy_evaluated>
This is either an unauthorized sender being actively blocked (if you are at p=reject) or a gap in your authentication coverage that you need to address before enforcing. Check the source IP via WHOIS to determine if this is a legitimate sender with missing configuration or spoofing traffic.
Understanding the difference betweenauth_results(raw crypto result) andpolicy_evaluated(alignment-aware result) is the single most important concept in reading DMARC reports. Most confusion in DMARC troubleshooting comes from not knowing which section is relevant to DMARC compliance.