Practice · DMARC reports

Interpreting DMARC aggregate reports

DMARC reports arrive as XML files — hundreds per month from hundreds of mail servers worldwide. If you understand the structure, you can read them even without a tool.

What is an aggregate report?

If your domain has a DMARC record with rua=mailto:…, receiving mail servers (Google, Microsoft, Yahoo and around 700 more) send an XML report every day. The report summarises which IPs sent mail with your From domain in the last 24 hours, whether they passed SPF and DKIM, and how the recipient ultimately handled them.

The report contains no mail content and no recipient addresses — only statistical aggregate data. RFC 7489 §7 defines the format (DMARC aggregate reporting, in short: aggregate report or rua).

The basic structure

A report XML consists of three main blocks:

Structure of an aggregate report<feedback>
  <report_metadata>       <!-- WHO sent the report, WHEN -->
    <org_name>Google</org_name>
    <email>[email protected]</email>
    <report_id>15748392026050801</report_id>
    <date_range>
      <begin>1715126400</begin>
      <end>1715212799</end>
    </date_range>
  </report_metadata>

  <policy_published>       <!-- WHICH policy was in effect at the time -->
    <domain>example.com</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>quarantine</p>
    <sp>quarantine</sp>
    <pct>100</pct>
  </policy_published>

  <record>                  <!-- WHAT was observed, per IP/auth combination -->
    <row>
      <source_ip>209.85.220.41</source_ip>
      <count>1842</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>
        <result>pass</result>
        <selector>google</selector>
      </dkim>
      <spf>
        <domain>example.com</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
</feedback>

The key fields in detail

report_metadata

policy_published

record / row

auth_results

Alignment ≠ authentication. A DKIM or SPF pass in the auth_results block only means the signature/IP was valid for some domain. Only the comparison with header_from (alignment) decides DMARC pass.

Three typical patterns you should spot immediately

Pattern 1: clean own-domain sending

source_ip belongs to your mail provider (Google, Microsoft, your own server), spf=pass, dkim=pass, policy_evaluated.dkim=pass and spf=pass. Large count. → All in order.

Pattern 2: provider with misalignment

spf=pass and dkim=pass, but policy_evaluated shows fail. Meaning: authentication itself worked, but for a different domain than the one in the From: header. Typical for newsletter tools (Mailchimp, Sendgrid) that use their own default domain for SPF/DKIM. → Sender must authenticate with its own domain.

Pattern 3: spoofing attempt

source_ip is an unknown IP (often from Asia or Eastern Europe), spf=fail, dkim=none or fail, count small to medium (~10–100). → Someone is trying to send mail in your name. With p=reject this mail is rejected automatically.

Why manual analysis does not scale

DMARC reports are XML — machine-readable, not human-readable. Even a small domain receives several reports daily from different recipients (Google, Microsoft, Yahoo, Apple, Comcast, …). Without aggregation you only see snapshots: an IP here, a DKIM fail there. Spoofing patterns, shadow-IT senders and drift only emerge once you correlate days and weeks across all recipients — including reverse DNS resolution of every source IP and provider mapping.

Open-source tools like the opendmarc parser or parsedmarc can split individual XML reports. The actual work — aggregation over time, provider detection, trend visualisation, drift alerts — you have to build and operate yourself. Feasible for a handful of reports per month, not for ongoing DMARC operations.

That is exactly what Mailantis is for: XMLs are ingested, aggregated, enriched with provider and geo detection and presented as a readable overview. Drift alerts fire automatically as soon as a new sender appears. All that is left of DMARC analysis is the part that actually requires decisions — not the XML parsing.

What to do after reading

Frequently asked questions

What do the most important XML fields mean?

report_metadata says who sent the report and when, policy_published what your DMARC policy was at the time, record/row the individual sender IPs with counts and auth results, auth_results the raw SPF/DKIM results before alignment is checked.

What is the difference between authenticated and aligned?

A DKIM or SPF pass in auth_results only means the signature/IP was valid for some domain. Only the comparison with header_from (alignment) decides DMARC pass.

Why am I seeing unknown IPs in my reports?

Three possible causes: legitimate service providers with misalignment (e.g. newsletter tools without custom auth), mail forwarding via third-party servers, or real spoofing attempts. DMARC reports make all three visible.

Do I also need forensic reports?

Usually no. Aggregate reports show which IPs fail SPF/DKIM. Forensic reports contain mail headers and are GDPR-sensitive; many recipients no longer send them at all for data-protection reasons.

Is manual analysis of the reports enough?

No. DMARC reports are XML, arrive daily from multiple recipients, and only become a useful picture after aggregation, provider detection and trend analysis over time. opendmarc/parsedmarc parse individual reports but leave you alone for aggregation and drift detection. Mailantis handles exactly that part automatically.