# DMARC reports: how to read aggregate (rua) reports and what to act on

> A DMARC report is the daily XML summary that Gmail, Outlook, Yahoo and other receivers send you about every server that used your domain. How to receive them, how to read each part, and which rows need action.

Updated 2026-09-26 · Security · HTML version: https://getreport.app/guides/dmarc-reports

A DMARC report is a daily summary, sent as a zipped XML file, from each mail provider that received mail using your domain. It lists every sending IP address, how many messages it sent, and whether they passed SPF and DKIM for your domain. You ask for these aggregate reports with the `rua` tag in your DMARC record, and reading them is how you find every service that sends as you before you move your policy to reject.

This guide is for whoever owns the domain's DMARC record and now has a mailbox full of attachments. You will know what each part of the report means, how to sort the rows, and what to do about each kind. If you have no DMARC record yet, start with the guide to [what DMARC is and your first record](https://getreport.app/guides/what-is-dmarc); the [SPF, DKIM and DMARC setup guide](https://getreport.app/guides/spf-dkim-dmarc-email-authentication) shows where reports fit in the rollout.

## Quick answer

- **Ask for reports** with `rua=mailto:dmarc@example.com` in the record at `_dmarc.example.com`.
- **Each receiver sends one report per day**, usually covering 24 hours, as a `.zip` or `.xml.gz` attachment.
- **Each `<record>` is one sending IP address** with a message count, the DMARC verdict for DKIM and SPF (`policy_evaluated`) and the raw checks behind it (`auth_results`).
- **Sort the rows into three groups:** your services passing, your services failing, and senders you do not recognise.
- **Fix your failing services**, usually by turning on DKIM for your domain in them, and only then tighten the policy.
- **Use a report reader** for anything beyond a handful of reports; the XML is not written for people.

## rua and ruf: the two kinds of DMARC report

DMARC defines two kinds of report, each requested with its own tag:

| Tag | Report | What it contains | How common |
| --- | --- | --- | --- |
| `rua` | Aggregate report (RFC 9990) | Counts per sending IP, with pass and fail results. No message content. | Sent by Google, Microsoft, Yahoo and most large receivers |
| `ruf` | Failure report (RFC 9991) | Details of single failing messages, sometimes with headers | Rare; most large receivers do not send them, for privacy reasons |

This guide is about aggregate reports, the ones you will actually receive. They contain no message bodies, subjects or recipient addresses: only IP addresses, domains, counts and results. That also makes them safe to hand to a report service.

## How to start receiving DMARC reports

Add a `rua` tag to your DMARC record:

```dns
_dmarc.example.com.  3600  IN  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
```

Three things to get right:

- **Use a dedicated mailbox.** A busy domain receives dozens of reports a day. A shared inbox fills up; a mailbox or alias only for reports, or a report service's address, is easier.
- **Several addresses are separated by commas:** `rua=mailto:dmarc@example.com,mailto:reports@dmarc-service.example`.
- **An address on another domain needs permission.** If `rua` points outside your domain, the receiving domain must publish a TXT record `v=DMARC1` at `example.com._report._dmarc.otherdomain.example`, or receivers will not send. Report services set this up for you.

Reports start arriving within one or two days. A domain that sends very little mail may receive only a few, since receivers only report on days when they saw your domain.

> **Check: DMARC reports.** The aggregate reports (rua) are how you find every service that sends as your domain before you tighten the policy. Without them you are guessing.
>
> 1. Add rua=mailto:dmarc@yourdomain (or the address of a free DMARC report reader) to the DMARC record.

The [email and DNS health check](https://getreport.app/tools/email-dns-check) shows whether your record asks for reports and where they go. It reads your DNS only; it does not collect or read the reports themselves.

## What a DMARC aggregate report looks like

Unzip an attachment and you get one XML file. Shortened, a report from one receiver looks like this:

```xml
<feedback>
  <report_metadata>
    <org_name>google.com</org_name>
    <report_id>1234567890123456789</report_id>
    <date_range>
      <begin>1758844800</begin>
      <end>1758931199</end>
    </date_range>
  </report_metadata>
  <policy_published>
    <domain>example.com</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>none</p>
    <sp>none</sp>
  </policy_published>
  <record>
    <row>
      <source_ip>198.51.100.23</source_ip>
      <count>112</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>pass</dkim>
        <spf>fail</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>example.com</header_from>
    </identifiers>
    <auth_results>
      <dkim>
        <domain>example.com</domain>
        <selector>s1</selector>
        <result>pass</result>
      </dkim>
      <spf>
        <domain>bounces.mailer.example.net</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
</feedback>
```

The parts, from top to bottom:

- **`report_metadata`** says who sent the report and which period it covers. The dates are Unix timestamps in seconds; the example covers one day in September 2026.
- **`policy_published`** is your DMARC record as the receiver read it. If it does not match what you think you published, the receiver saw an older or a different record.
- **`record`** appears once per sending IP address and result. A report can hold hundreds.

## How to read DMARC reports, row by row

Each `<record>` answers four questions:

1. **Who sent it?** `source_ip` is the sending server. `count` is how many messages it sent with your domain in the From line (`header_from`) during the period.
2. **Did DMARC pass?** Look at `policy_evaluated`. `dkim` and `spf` there are the **aligned** results: pass means that check passed *for your domain*. DMARC passes when either one says pass.
3. **What happened to the mail?** `disposition` is what the receiver did: `none` (delivered normally), `quarantine` (spam folder) or `reject`. Under `p=none` it is always `none`.
4. **Why?** `auth_results` shows the raw SPF and DKIM checks with the domain each one used, and the DKIM selector.

The difference between the two blocks is the key to reading reports. In the example, `auth_results` shows SPF passing, but for `bounces.mailer.example.net`, so the aligned SPF result in `policy_evaluated` is fail. DKIM passed for `example.com` with selector `s1`, so DMARC passed. This is normal for a newsletter tool that uses its own bounce domain and signs with yours.

## What to act on: the four patterns

Sort the rows into groups by what they show:

| `policy_evaluated` | Source | Meaning | Action |
| --- | --- | --- | --- |
| DKIM pass (SPF either) | Your service | Healthy | None |
| DKIM fail, SPF pass | Your service | Passing through SPF only; breaks when forwarded | Turn on DKIM for your domain in that service |
| DKIM fail, SPF fail | Your service | Fails DMARC; will be blocked under reject | Set the service up for your domain, then recheck |
| DKIM fail, SPF fail | Unknown IP | Spoofing, or a tool nobody told you about | Identify the owner before deciding |

A few more patterns worth knowing:

- **DKIM passes for the service's domain, not yours** (`auth_results` shows `sendgrid.net` or `onmicrosoft.com`). The service signs, but not as you. Finish its custom-domain DKIM setup.
- **Small counts that fail from IPs belonging to Google, Microsoft or other mailbox providers.** Usually forwarding: someone forwarded your mail on, SPF broke, and DKIM survived or did not. You cannot fix other people's forwarders; DKIM on every message is the protection.
- **Thousands of failing messages from IPs in unrelated networks.** Someone is sending as your domain. That is what `p=reject` is for.

## How to identify an unknown sending IP

Before calling an IP spoofing, find out who owns it:

1. **Reverse DNS.** `dig +short -x 198.51.100.23` often returns a host name that names the service, such as `mail-sor-f41.google.com` or `o1.email.example-mailer.net`.
2. **The network owner.** An IP WHOIS or RDAP lookup names the organisation that holds the address block.
3. **Ask around.** Marketing, sales, finance and support often sign up for tools that send mail as the company without telling IT.

Report readers do the first two for you and group IPs by organisation, which turns hundreds of rows into a list of a dozen senders.

## Using a report reader

Reading XML by hand works for your first few reports. After that, a report reader, also called a DMARC analyser, collects reports at its own address, unzips them, groups them by sender and shows trends. Many offer a free plan for low volumes, and there are open-source parsers you can run yourself.

Two things to consider before you choose one. The service sees your sending data: IP addresses and volumes, not message content. And your `rua` then points to its domain, so if you stop using it, change the record, or reports go on flowing to a service you no longer read.

## What changed with RFC 9990

In May 2026 the IETF replaced RFC 7489 with three documents, and RFC 9990 now defines aggregate reports. Existing parsers keep working, but the format was tightened:

- The XML has a formal namespace and schema, and each report covers one DMARC policy domain.
- When DKIM results are reported, the selector is required, which makes key rotation easier to follow.
- New optional fields reflect the other changes in RFC 9989, such as the `np` policy for subdomains that do not exist and the `t=y` testing flag, plus how the receiver discovered your policy.
- The `ri` tag, which asked for a report interval, was removed. Receivers send daily reports.

## When the reports say you are ready

Your domain is ready for the next policy step when, over two to four weeks of reports:

- every service you recognise shows DKIM pass in `policy_evaluated`, or at least aligned SPF;
- the only failing rows are forwarding and senders you have confirmed are not yours.

Then move from `p=none` to `p=quarantine`, and later to `p=reject`, as the [DMARC policy guide](https://getreport.app/guides/dmarc-policy-none-quarantine-reject) describes. Keep `rua` in the record at every step: the reports are how you notice the next tool someone signs up for.

## Questions people ask

### How do I read DMARC reports?

Open the XML and look at each `<record>`: the sending IP, the message count, and whether DKIM and SPF passed in `policy_evaluated`. Group the rows into your services passing, your services failing and unknown senders. Fix the failing services, usually by turning on DKIM for your domain, and only then tighten the policy. A report reader turns the XML into a table.

### What is a DMARC rua address?

It is the address in the `rua` tag of your DMARC record where receivers send aggregate reports, for example `rua=mailto:dmarc@example.com`. Use a mailbox dedicated to reports or a report service's address. If the address is on a different domain from yours, that domain must publish a record allowing it, or receivers will not send reports there.

### Why am I not receiving DMARC reports?

Usually because the `rua` tag is missing or mistyped, it points to another domain that has not authorised it, or the record itself is broken and receivers ignore it. Reports also only come from receivers that saw your mail that day, so a quiet domain gets few. Check the record with an email DNS checker and wait two days.

### Do mailbox providers still send DMARC failure (ruf) reports?

Rarely. Failure reports can contain parts of individual messages, so most large receivers do not send them for privacy reasons. You can still add a `ruf` address; some smaller receivers use it. For almost every domain, the daily aggregate reports from the `rua` tag are all you need to find failing senders.

### What does disposition none mean in a DMARC report?

It means the receiver delivered the messages normally and applied no DMARC action. Under `p=none` every row shows `none`, even the failing ones, because the policy only asks for monitoring. Under quarantine or reject, `none` means those messages passed, or a local rule such as a forwarding exception overrode your policy.

### How often are DMARC aggregate reports sent?

Once a day from each receiver that saw mail from your domain, usually covering a 24-hour period in UTC. RFC 9989 removed the old `ri` tag that asked for a different interval, so there is nothing to set. Expect the first reports a day or two after publishing the record, from Google, Microsoft, Yahoo and others.
