All dispatchesView as Markdown

How to read DMARC reports: turn XML into an action plan

MC
Maya ChenEmail infrastructure at Email Bump

Read DMARC aggregate reports with the current RFC 9990 fields, separate authentication from alignment, identify legitimate senders, investigate failures, and measure policy readiness.

A DMARC aggregate report is a receiver's summary of mail that used your domain in the visible From address. It groups messages by connecting IP, authentication result, alignment result, and policy disposition. The report can reveal forgotten senders, broken DKIM, forwarding patterns, and direct spoofing—but it does not name an individual recipient or prove that a message reached the inbox.

The useful question is not simply “what percentage passed?” It is “which real mail stream produced each row, which aligned identity made it pass or fail, and what should the domain owner change?” This guide turns the XML into that investigation.

What DMARC reports tell you

Evidence and boundary
A REPORT CAN SHOW                    IT CANNOT PROVE
Connecting sending IP                The person who pressed Send
Message count for an aggregated row  One row per individual message
Visible From domain                  Message subject, body, or recipient
SPF and DKIM validation results      That an authenticated message was wanted
DMARC alignment pass or fail         Inbox placement or human reading
Requested/applied disposition        That every receiver applied the same policy
Receiver-declared override reason    That reverse DNS identifies the true owner

Aggregate reports are requested with the rua tag in a DMARC record. Participating receivers generally send one report for a reporting period, often daily, and aggregate equivalent outcomes. Coverage is valuable but incomplete: receivers choose whether to report, can apply local limits, and may describe the same provider through several IPs and rows.

Read the report from the outside in

Current DMARC aggregate report shapexml
<feedback xmlns="urn:ietf:params:xml:ns:dmarc-2.0">
  <version>1.0</version>
  <report_metadata>
    <org_name>Example Receiver</org_name>
    <report_id>[email protected]</report_id>
    <date_range><begin>1785801600</begin><end>1785887999</end></date_range>
  </report_metadata>
  <policy_published>
    <domain>example.com</domain><p>quarantine</p><sp>none</sp>
  </policy_published>
  <record>
    <row>
      <source_ip>192.0.2.24</source_ip><count>842</count>
      <policy_evaluated>
        <disposition>pass</disposition><dkim>pass</dkim><spf>fail</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <envelope_from>bounces.mail.example.com</envelope_from>
      <header_from>example.com</header_from>
    </identifiers>
    <auth_results>
      <dkim><domain>mail.example.com</domain><selector>tx1</selector><result>pass</result></dkim>
      <spf><domain>provider.example</domain><result>pass</result></spf>
    </auth_results>
  </record>
</feedback>
  • report_metadata identifies the receiver, unique report, and UTC reporting window. Deduplicate by reporter and report ID before aggregating counts.
  • policy_published records the DMARC policy the receiver discovered for the policy domain during that report.
  • row contains the connecting source IP, message count, DMARC-aligned SPF/DKIM results, disposition, and possible override reasons.
  • identifiers contains the visible header_from domain and, when available, envelope domains used during evaluation.
  • auth_results records raw DKIM signatures and SPF validation. These results are not automatically aligned with the visible From domain.

Do not confuse authentication with DMARC alignment

A raw SPF result can pass for a provider-owned return-path while DMARC's SPF alignment fails because that domain is unrelated to the visible From domain. A DKIM signature can likewise validate cryptographically but use a d= domain that is not aligned. DMARC passes when at least one supported path both authenticates and aligns: SPF or DKIM.

Four common rows
DMARC DKIM  DMARC SPF  USUAL INTERPRETATION
pass        pass        Redundant aligned authentication; healthy direct route
pass        fail        Common and valid: aligned DKIM carries DMARC
fail        pass        Aligned envelope path carries DMARC; inspect DKIM separately
fail        fail        DMARC fail: unknown source, configuration error, or indirect flow

The policy_evaluated dkim/spf fields describe DMARC alignment outcomes.
The auth_results fields describe the underlying authentication checks.

For each row, compare header_from with the SPF domain and every DKIM d= domain. Apply the domain's relaxed or strict alignment mode. Then ask whether the passing identity belongs to the expected service. A DMARC pass from an unknown but authorized integration is still an inventory finding.

Triage every source into an owner and purpose

  • Match the source against provider-published IP ranges, your sending logs, DKIM selectors, return-path domains, timestamps, and volume shape.
  • Use reverse DNS and network ownership as clues, not proof; shared clouds and email providers host many unrelated tenants.
  • Record a business owner, service owner, message purpose, expected domains, expected selectors, and retirement date for every legitimate stream.
  • Separate forwarders and mailing lists from direct sources. Forwarding commonly breaks SPF, while content modification can also break DKIM.
  • Classify an unresolved source as unknown until evidence identifies it. Do not authorize an IP just to make a report row green.
Practical source inventory
SOURCE / CIDR   OWNER       PURPOSE        EXPECTED AUTH                    STATE
Provider A      Product     receipts       DKIM d=mail.example.com s=tx1    approved
CRM vendor      Marketing   newsletters    SPF bounce.example.com + DKIM    approved
Forwarder       IT          aliases        DKIM expected; SPF may fail       indirect
Old VM          unknown     low volume     both fail                         investigate
Cloud host      unknown     burst          both fail                         likely abuse

Store evidence and first/last seen dates. Names alone are not controls.

Interpret disposition and policy overrides carefully

Disposition describes the DMARC action reported for that row; it is not a mailbox-placement verdict. A receiver can override the published policy for local policy, a mailing list, a trusted forwarder, or another declared reason. Conversely, a p=none policy can produce failing rows with disposition none because the domain only asked for monitoring.

Do not conclude that DMARC is ineffective because a failing row was delivered, or that reject is safe because the current disposition says none. First determine whether the row is legitimate, whether an override occurred, and whether the configured policy was actually eligible to apply to that From domain and subdomain.

Calculate metrics that lead to action

Weighted DMARC metrics
total_messages       = sum(row.count)
aligned_messages     = sum(count where DMARC DKIM pass OR DMARC SPF pass)
unknown_failures     = sum(count where both fail AND source is unowned)
known_broken_mail    = sum(count where both fail AND source is legitimate)
indirect_failures    = sum(count classified as forwarding or mailing list)

alignment_rate      = aligned_messages / total_messages
unknown_failure_rate = unknown_failures / total_messages

Never average row percentages. A row with count=50,000 outweighs one with count=2.

Segment by receiver, source, header From domain, DKIM domain and selector, SPF domain, and policy result. A global pass rate can hide a complete failure at one mailbox provider or one critical stream. Track new sources and material changes in count as well as the percentage that passes.

Move from p=none to enforcement with evidence

  • Run long enough to observe weekly, monthly, billing, security, and seasonal senders—not merely one quiet day.
  • Repair aligned DKIM for every legitimate service; it is especially important through forwarding paths.
  • Remove abandoned vendors and credentials instead of preserving permanent authorization for old mail streams.
  • Investigate receiver-specific and subdomain-specific failures, including inherited sp and non-existent-domain policy behavior.
  • Canary enforcement on a controlled subdomain or percentage only when you can measure the affected traffic and reverse safely.
  • Monitor new failures, support reports, and receiver evidence after each policy change before advancing further.

Ingest DMARC XML as hostile input

Reports arrive as external email and compressed attachments. Limit compressed and expanded size, number of archive members, XML depth, element count, and processing time. Disable external entities and network resolution in the XML parser. Validate the report structure, isolate malformed files, deduplicate report IDs, retain the original artifact under restricted access, and never render free-text comments as trusted HTML.

Frequently asked questions

What does a DMARC report failure mean?

It means neither the SPF-authenticated domain nor a passing DKIM signing domain aligned with the visible From domain for that aggregated row. The cause can be unauthorized sending, a legitimate service with incorrect alignment, forwarding, mailing-list modification, or another indirect path. Identify the source and compare raw authentication with alignment before changing DNS.

Why does SPF pass in auth_results but fail under policy_evaluated?

The SPF check authenticated an envelope domain, but that domain did not align with the visible From domain under DMARC. This is common when a provider uses its own return-path. Configure a custom aligned return-path where supported or rely on aligned DKIM.

Do DMARC reports contain recipients or message content?

Aggregate reports contain message counts and authentication metadata, not message bodies or individual recipient addresses. They still reveal infrastructure and traffic patterns, so protect report storage and review the privacy implications of sending reports to a third-party processor.