# How to read DMARC reports

URL: https://iblockspam.com/blog/how-to-read-dmarc-reports
Last updated: 2026-10-09
Published: 2026-10-09
Topic: SPF, DKIM & DMARC
Author: iBlockSpam Team

> A field-by-field guide to DMARC aggregate (rua) reports under RFC 9990: spot your real senders, tell forwarding from spoofing, and know when you can enforce.

## Short answer

A DMARC aggregate report is a daily XML file from a receiver. It lists each sending IP, how many messages it sent as your domain, and whether SPF and DKIM passed and aligned. Group rows by source: your own services should pass. Fix legitimate senders that fail, ignore forwarders, and treat unknown failing sources as spoofing.

DMARC aggregate reports are the main way to see who is sending mail as your domain across the internet. They arrive as compressed XML attachments that are hard to read by eye. To turn one into a readable table, drop the file into our free [DMARC Report Analyzer](https://iblockspam.com/tools/dmarc-report-analyzer), which parses it in your browser. This guide explains every part of a report under [RFC 9990](https://www.rfc-editor.org/rfc/rfc9990.html), shows how to sort the rows into "fix", "ignore" and "block", and tells you when the data is good enough to move to enforcement.

## What is a DMARC aggregate report?

When your DMARC record includes `rua=mailto:...`, receivers that support reporting send you a summary of the mail they saw using your domain. Since May 2026 the format is defined in RFC 9990, which replaced the schema in [RFC 7489 Appendix C](https://www.rfc-editor.org/rfc/rfc7489.html#appendix-C). RFC 9990 describes reports as "daily (or more frequent)" and says a period typically covers "a single UTC day, beginning at 0000UTC".

Each report is an email with the XML attached. RFC 9990 says the XML should be GZIP-compressed, and the file name follows this pattern:

```
receiver!your-domain!begin-timestamp!end-timestamp.xml.gz
```

[Google](https://knowledge.workspace.google.com/admin/security/about-dmarc-reports) notes that every server you send mail to may send its own daily report, and that large organizations can receive hundreds or thousands a day. Both Google and [Microsoft](https://learn.microsoft.com/en-us/defender-office-365/email-authentication-dmarc-configure) suggest using a DMARC reporting service or your own tooling to parse them. Microsoft also advises sending reports to a dedicated mailbox or group, not a user's inbox.

If your reports go to a mailbox on a different domain, that domain must authorize it with a record at `yourdomain._report._dmarc.otherdomain`. RFC 9990 says that if the check fails, the receiver "MUST" ignore the address. Our [DMARC record examples](https://iblockspam.com/blog/dmarc-record-examples) show the exact record.

## What does a DMARC report look like?

Here's a shortened report for `example.com`, with two records:

```xml
<feedback xmlns="urn:ietf:params:xml:ns:dmarc-2.0">
  <version>1.0</version>
  <report_metadata>
    <org_name>receiver.example</org_name>
    <email>dmarc-noreply@receiver.example</email>
    <report_id>20261008.example.com.1</report_id>
    <date_range><begin>1791417600</begin><end>1791503999</end></date_range>
  </report_metadata>
  <policy_published>
    <domain>example.com</domain>
    <p>none</p>
    <adkim>r</adkim>
    <aspf>r</aspf>
  </policy_published>
  <record>
    <row>
      <source_ip>192.0.2.10</source_ip>
      <count>412</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>pass</dkim>
        <spf>fail</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>example.com</header_from>
      <envelope_from>bounces.mailer.example</envelope_from>
    </identifiers>
    <auth_results>
      <dkim><domain>example.com</domain><selector>s1</selector><result>pass</result></dkim>
      <spf><domain>bounces.mailer.example</domain><result>pass</result></spf>
    </auth_results>
  </record>
  <record>
    <row>
      <source_ip>203.0.113.77</source_ip>
      <count>36</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>fail</dkim>
        <spf>fail</spf>
      </policy_evaluated>
    </row>
    <identifiers><header_from>example.com</header_from></identifiers>
    <auth_results>
      <spf><domain>example.com</domain><result>fail</result></spf>
    </auth_results>
  </record>
</feedback>
```

The first row is a legitimate mailing service: DKIM is signed with your domain, so DMARC passes even though SPF doesn't align. The second row is an unknown IP failing everything: likely spoofing.

The `begin` and `end` values here are 8 October 2026, 00:00:00 to 23:59:59 UTC. Reports from receivers still using the older RFC 7489 schema look slightly different: they lack the newer elements such as `np` and `testing`, and may include `pct`. Microsoft's own sample report, for example, still shows a `pct` element.

## What does each field mean?

### report_metadata and policy_published

| Field | What it tells you |
|---|---|
| `org_name`, `email` | Who sent the report |
| `report_id` | Unique per report; use it to spot duplicates |
| `date_range` `begin` / `end` | Period covered, in seconds since the epoch (UTC) |
| `error` | Problems the receiver had, such as errors evaluating your DMARC record |
| `policy_published` | Your DMARC record as the receiver saw it: `domain`, `p`, `sp`, `np`, `adkim`, `aspf`, `fo`, `testing` |
| `discovery_method` | `psl` or `treewalk`: how the receiver found your organizational domain |

Check `policy_published` first. If it doesn't match what you think you published, the receiver may have cached an old record, or found a different one.

### record: one row per source

| Field | What it tells you |
|---|---|
| `source_ip` | The IP that connected to the receiver |
| `count` | How many messages matched this row |
| `disposition` | What the receiver applied: `none`, `pass`, `quarantine` or `reject` |
| `policy_evaluated` `dkim` / `spf` | **Aligned** result for DMARC: only `pass` or `fail` |
| `reason` | Why the receiver overrode your policy, if it did |
| `header_from` | The domain in the visible From address |
| `envelope_from` | The MAIL FROM (return-path) domain; optional |
| `auth_results` `dkim` | Each DKIM signature's `domain`, `selector` and raw `result` |
| `auth_results` `spf` | The SPF `domain` checked and the raw `result` |

The most common confusion is between the two places that show SPF and DKIM. `auth_results` gives the raw result: did the signature verify, did SPF pass for *that* domain? `policy_evaluated` gives the result DMARC used: did it pass **and** align with your From domain? An SPF `pass` in `auth_results` with `fail` in `policy_evaluated` means the service is authorized for its own domain but not aligned with yours.

RFC 9990 defines `disposition=pass` as "No action, passing DMARC w/enforcing policy". `none` means no action was taken.

### reason: policy overrides

Receivers can ignore your policy and say why. The allowed types are `local_policy`, `mailing_list`, `trusted_forwarder`, `policy_test_mode` and `other`. A `mailing_list` or `trusted_forwarder` reason usually means the receiver recognized a forwarding path and delivered mail that technically failed.

## How do you tell legitimate senders from spoofing?

Group rows by `source_ip` and look up who owns each IP. A reverse DNS name often tells you; the [PTR Lookup](https://iblockspam.com/tools/ptr-lookup) helps. Then sort each source into one of these patterns:

| Pattern | Likely meaning | What to do |
|---|---|---|
| Your mail platform's IPs, SPF and DKIM aligned | Normal staff mail | Nothing |
| Known service, DKIM `pass` but signed with the service's domain | Service not set up for your domain | Set up custom DKIM at the service |
| Known service, SPF raw `pass`, aligned `fail`, no aligned DKIM | Service uses its own return-path | Custom DKIM, or a custom return-path on your domain |
| Known service, SPF and DKIM both `fail` | Service not in SPF and not signing | Add it to SPF and set up DKIM, or stop using it |
| Mailbox provider IPs, SPF `fail`, DKIM `pass` and aligned | Forwarded mail | Nothing; DKIM carried it |
| Mailing list IPs, everything fails | List changed the message and resent it | Usually nothing |
| Unknown IPs, everything fails, From is your domain | Spoofing | Your enforcement policy is what stops it |

Forwarding is the main source of false alarms. [RFC 9989 section 7.4](https://www.rfc-editor.org/rfc/rfc9989.html) says forwarded mail "will most likely fail SPF checks" unless the forwarder rewrites the envelope sender, while "DKIM signatures will generally remain valid". That's why aligned DKIM matters more than SPF before you enforce.

Be careful with low counts. One or two messages from a home IP may be a staff member's phone app or a printer. Ask before you assume it's an attack.

## What about failure (forensic) reports?

The `ruf` tag requests failure reports: one report per failing message, defined in [RFC 9991](https://www.rfc-editor.org/rfc/rfc9991.html). They use the Abuse Reporting Format and can include headers and parts of the message. RFC 9991 warns that they "may include PII and non-public information", recommends redaction, and notes that many large providers limit or disable them. Microsoft 365 doesn't send them at all, even if your record asks.

In contrast, RFC 9990 says aggregate reports contain no personal information such as individual mail addresses, and no message content. For most domains, aggregate reports are enough.

## When are you ready to enforce?

RFC 9989 is clear that `p=none` comes first. Section 5.1.5 says the reason "is to ensure that nothing's been missed in the initial SPF and DKIM deployments". Section 5.1.7 warns it "may take many months of consuming DMARC aggregate reports" to get there.

Use this checklist before moving from `p=none` to `quarantine`:

1. Every source you recognize passes DMARC through aligned DKIM, aligned SPF, or both.
2. The remaining failures are forwarding, mailing lists, or sources you've confirmed are not yours.
3. You've had at least a few weeks of reports, covering month-end, payroll and newsletters.
4. Reports come from the large mailbox providers your recipients use.
5. Subdomains that send mail have their own SPF and DKIM.

Then follow a staged rollout. [Moving DMARC from p=none to p=reject](https://iblockspam.com/blog/dmarc-none-to-reject-small-business) covers it step by step, and the [DMARC Generator](https://iblockspam.com/tools/dmarc-generator) builds each stage's record. Keep reading reports after you enforce. A new tool someone signs up for will show up there first.

## Next steps

1. Check your record with the [DMARC Checker](https://iblockspam.com/tools/dmarc-checker) and confirm it has a working `rua` address.
2. Send reports to a dedicated mailbox, and use a parser or reporting service rather than reading raw XML. For a single file, the [DMARC Report Analyzer](https://iblockspam.com/tools/dmarc-report-analyzer) groups the rows by sender and shows what fails.
3. For each failing service, confirm SPF with the [SPF Checker](https://iblockspam.com/tools/spf-checker) and DKIM with the [DKIM Checker](https://iblockspam.com/tools/dkim-checker).
4. Read [SPF vs DKIM vs DMARC](https://iblockspam.com/blog/spf-vs-dkim-vs-dmarc) or [what DMARC is](https://iblockspam.com/blog/what-is-dmarc) if alignment still feels unclear.
5. If a source keeps failing and the table above doesn't explain it, work through [why DMARC fails](https://iblockspam.com/blog/why-dmarc-fails).

iBlockSpam's [domain monitoring](https://iblockspam.com/features/domain-monitoring) alerts you when your MX, SPF or DMARC records change. Its [DMARC monitoring](https://iblockspam.com/features/dmarc-monitoring), included in Protect and Protect Plus, collects these aggregate reports for you once you add `rua=mailto:dmarc@iblockspam.com` to your record: it shows who sends as your domain, what passes, and when it's safe to tighten your policy. It reports on mail; it doesn't block anything by itself.

Browse our other [SPF, DKIM and DMARC guides](https://iblockspam.com/blog/topic/authentication).

## Frequently asked questions

### How often are DMARC aggregate reports sent?

RFC 9990 describes them as daily or more frequent, and says a report typically covers a single UTC day starting at midnight. Google says every mail server you send email to will send you a daily report. Each receiver that gets mail from your domain sends its own report, so a busy domain can get many files each day.

### Why does a report show SPF pass but DMARC fail?

Because DMARC needs alignment, not just a pass. If a service sends with its own domain in the envelope sender, SPF passes for that domain but doesn't align with your From domain. Look at policy_evaluated: spf=fail there means not aligned. Fix it with custom DKIM signing or a custom return-path at the service.

### Do DMARC aggregate reports contain personal data?

RFC 9990 says aggregate reports contain no personal information such as individual mail addresses and no message content. They hold IP addresses, counts, domains and authentication results. Failure reports are different: RFC 9991 warns they may include personal and non-public information from the failing messages.

### Why am I not getting DMARC reports from some receivers?

Not every receiver sends reports, as Microsoft notes in its DMARC guidance. Also check that your rua address uses mailto:, that the mailbox accepts large compressed attachments, and that any reporting address on another domain is authorized with a _report._dmarc record. Without that record, receivers must ignore the address.

### Should I ask for ruf failure reports?

Usually not at first. Microsoft 365 doesn't send them at all, and RFC 9991 notes many large providers limit or disable them. They can contain message content. Start with aggregate reports, which show the same sources without the privacy risk, and add ruf only if you have a specific need.

## Sources

- [RFC 9990: DMARC Aggregate Reporting](https://www.rfc-editor.org/rfc/rfc9990.html)
- [RFC 9991: DMARC Failure Reporting](https://www.rfc-editor.org/rfc/rfc9991.html)
- [RFC 9989: DMARC, section 5.1 (Domain Owner actions)](https://www.rfc-editor.org/rfc/rfc9989.html)
- [RFC 7489, Appendix C: DMARC XML Schema (obsoleted)](https://www.rfc-editor.org/rfc/rfc7489.html#appendix-C)
- [Microsoft Learn: Set up DMARC to validate email in Microsoft 365](https://learn.microsoft.com/en-us/defender-office-365/email-authentication-dmarc-configure)
- [Google Workspace Admin Help: About DMARC reports](https://knowledge.workspace.google.com/admin/security/about-dmarc-reports)

## Free tools for this guide

- [DMARC Report Analyzer](https://iblockspam.com/tools/dmarc-report-analyzer): Read DMARC aggregate reports (XML, gzip or zip): see who sends as your domain and what fails — runs in your browser.
- [DMARC Checker](https://iblockspam.com/tools/dmarc-checker): Check your policy, reporting and the safe path from p=none to reject.
- [DMARC Record Generator](https://iblockspam.com/tools/dmarc-generator): Build a DMARC record with the right policy, reporting and alignment settings.
- [SPF Checker](https://iblockspam.com/tools/spf-checker): Count real DNS lookups, find PermErrors, loops and risky "all" settings.

---

Source: iBlockSpam, https://iblockspam.com/blog/how-to-read-dmarc-reports (this is a Markdown copy; the HTML page is canonical). Quote with attribution and a link. Site index for AI assistants: https://iblockspam.com/llms.txt
