The anatomy of a DMARC report

A DMARC aggregate report is just structured data. But when it’s raw, it feels overwhelming: nested tags, timestamps, policies, alignment results, and IP addresses.

In this article, we’ll walk through a DMARC aggregate report – block by block – and explain what each part actually means, including fields introduced in the updated DMARC specification (DMARCbis).

There are three main building blocks:

  1. Report and generator meta data – who sent the report and what time period it covers
  2. DMARC policy published – the policy that was in place for your domain
  3. One or more email batches – batches of emails sharing the same verification results

Report and generator meta data

The <report_metadata> block answers who generated this report and what time period it covers.

<feedback xmlns="urn:ietf:params:xml:ns:dmarc-2.0">
  <version>1.0</version>
  <report_metadata>
    <org_name>example.com</org_name>
    <email>dmarc@example.com</email>
    <extra_contact_info lang="en">
      https://support.example.com/a/answer/1234
    </extra_contact_info>
    <report_id>42</report_id>
    <error lang="en">An optional error message.</error>
    <generator>
      Example DMARC Aggregate Reporter v1.2
    </generator>
    <date_range>
      <begin>1715126400</begin>
      <end>1715212799</end>
    </date_range>
  </report_metadata>

Fields:

  • <org_name> - The organization which generated the report.
  • <email> - A contact address for the report generator.
  • <extra_contact_info> - Optional additional generator context.
  • <report_id> - A unique identifier for this specific report picked by the generator. This is useful for deduplication.
  • <error> - Optional error note.
  • <generator> - Optional name and version of the software that generated the DMARC report. This is useful when troubleshooting report inconsistencies or reporting bugs (introduced in DMARCbis).
  • <date_range> - The reporting window in Unix epoch time (seconds since January 1, 1970 UTC). It is common practice to send one report per DMARC record per day.

DMARC policy published

The <policy_published> block reflects the DMARC record that the receiving server found in DNS.

  <policy_published>
    <domain>example.com</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>none</p>
    <sp>none</sp>
    <np>none</np>
    <discovery_method>psl</discovery_method>
    <pct>100</pct>
    <fo>0</fo>
    <testing>n</testing>
  </policy_published>

Fields:

  • <domain> - The domain whose DMARC record was evaluated. Here, the record was found at _dmarc.example.com.
  • <discovery_method> - Indicates how the receiver determined the Organizational Domain when locating the DMARC policy.
    • psl - The receiver used the Public Suffix List (PSL) to determine the Organizational Domain.
    • treewalk - The receiver used the tree-walk discovery method introduced in DMARCbis.
  • <adkim> - DKIM alignment mode (r for relaxed, s for strict).
  • <aspf> - SPF alignment mode (r for relaxed, s for strict).
  • <p> - The domain-level DMARC policy (none, quarantine, or reject).
  • <sp> - The subdomain DMARC policy to be applied if there’s no separate DMARC record for a subdomain (none, quarantine, or reject).
  • <np> - The non-existent domain DMARC policy to be applied if an email is sent from a subdomain that returns NXDOMAIN in DNS (none, quarantine, or reject; introduced in DMARCbis).
  • <pct> - Percentage of emails to which the DMARC policy should be applied.
  • <fo> - Failure reporting options for DMARC forensic reports.
  • <testing> - Whether the domain is in testing mode (y or n; introduced in DMARCbis).

Email batches

Each <record> block represents a batch of emails from a single source IP that share the same verification results.

  <record>
    <row>
      <source_ip>51.159.167.134</source_ip>
      <count>42</count>

Fields:

  • <source_ip> - The IP address from which the email batch was received by the inbox provider. This is the most important field for investigation.
  • <count> - The number of emails seen from this IP address during the reporting period that match the same verification results.

DMARC result

The <policy_evaluated> block shows the result of DMARC evaluation, after SPF and DKIM were checked.

      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>pass</dkim>
        <spf>pass</spf>
        <reason>
          <type>local_policy</type>
          <comment lang="en">
            This is a local policy override comment.
          </comment>
        </reason>
      </policy_evaluated>
    </row>

Fields:

  • <disposition> - Reflects how the receiver applied your DMARC policy to this batch of emails. It does not guarantee final delivery outcome, as receivers may still reject or filter the message due to internal spam or security rules. Possible values:
    • none - No DMARC enforcement was applied.
    • pass - The message passed DMARC evaluation. No enforcement was applied, even though the domain may be operating with a quarantine or reject policy (introduced in DMARCbis).
    • quarantine - Emails failed DMARC and the policy requested that it be treated as suspicious, typically routed to spam.
    • reject - Emails failed DMARC and the policy requested that it be rejected during delivery.
  • <dkim> - Whether DKIM passed DMARC evaluation. This means the signature was valid and the signing domain aligned with the Header From domain. Possible values:
    • pass - The DKIM signature was valid and aligned.
    • fail - DKIM was missing, invalid, or not aligned.
  • <spf> - Whether SPF passed DMARC evaluation. This means the sending IP was authorized by SPF and the Envelope From domain aligned with the Header From domain. Possible values:
    • pass - SPF authentication succeeded and was aligned.
    • fail - SPF authentication failed or was not aligned.

This block may contain one or more <reason> blocks that explain why the receiver overrode or adjusted the DMARC policy for these emails. Each block includes:

  • <type> - The policy override type. Possible values:
    • local_policy - The receiver applied its own local rule instead of the requested DMARC enforcement.
    • mailing_list - The emails likely passed through a mailing list that modified it in a way that caused authentication to fail.
    • policy_test_mode - The receiver treated the domain as being in testing mode and did not apply enforcement.
    • trusted_forwarder - The emails were forwarded by a source the receiver considers as known and trusted, even though authentication failed.
    • sampled_out - The message was excluded from enforcement due to the pct percentage setting in the DMARC DNS record.
    • forwarded - The message was likely forwarded, and authentication failed as a result.
    • other - An override was applied that does not match the standard categories. Additional context may appear in <comment>.
  • <comment> - Optional additional details provided by the receiver.

Identifying domains

The <identifiers> block shows the domains found in the message envelopes and headers.

    <identifiers>
      <header_from>example.com</header_from>
      <envelope_from>example.com</envelope_from>
      <envelope_to>example.net</envelope_to>
    </identifiers>

Fields:

  • <header_from> - The domain in the visible Header From address. This is the primary domain DMARC protects and the one alignment is measured against.
  • <envelope_from> - Optional domain used in the envelope (also known as the Return-Path or Mail From). This is the domain SPF authenticates and may align with Header From.
  • <envelope_to> - Optional recipient domain used during delivery. This field is not used for DMARC evaluation.

Underlying SPF & DKIM auth results

The <auth_results> block shows the raw SPF and DKIM verification results before DMARC alignment logic is applied.

    <auth_results>
      <spf>
        <domain>example.com</domain>
        <scope>mfrom</scope>
        <result>pass</result>
        <human_result lang="en">
          More descriptive information relating to failures.
        </human_result>
      </spf>
      <dkim>
        <domain>example.com</domain>
        <selector>default</selector>
        <result>pass</result>
        <human_result lang="en">
          More descriptive information relating to failures.
        </human_result>
      </dkim>
    </auth_results>
  </record>
</feedback>

SPF authentication result fields:

  • <domain> - The domain that was evaluated by SPF.
  • <scope> - Indicates which identity SPF was evaluated against:
    • mfrom - SPF checked the Envelope From domain (assumed when omitted).
    • helo - SPF checked the HELO/EHLO domain.
  • <result> - The underlying SPF authentication result (none, neutral, pass, fail, softfail, policy, temperror, or permerror).
  • <human_result> - Optional explanatory text provided by the generator (introduced in DMARCbis).

DKIM authentication result fields:

  • <domain> - The domain from the DKIM signature (d=example.com).
  • <selector> - The DKIM selector (s=default) used to locate the public key in DNS.
  • <result> - The DKIM verification result (none, pass, fail, policy, neutral, temperror, or permerror).
  • <human_result> - Optional explanatory text provided by the generator.

Resources