# DMARC Aggregate Reports: How to Read rua XML

URL: https://email-validation.org/guides/dmarc-aggregate-reports/
Updated: 2026-11-06

> Documentation index: https://email-validation.org/llms.txt

A DMARC aggregate report is an XML file that a receiving mail system sends, usually once a day, to the address in
the `rua` tag of your DMARC record. It lists every IP address that sent mail with your domain in the From: header
during the period, how many messages each sent, and whether SPF and DKIM passed and aligned with your domain. It
contains no message content. Read it to find the services you forgot to authenticate before you
[tighten your policy](https://email-validation.org/guides/dmarc-none-to-reject/), and to spot forgeries of your domain.

## Where the format is defined

Aggregate reports were first specified in [RFC 7489](https://www.rfc-editor.org/info/rfc7489/), section 7.2, with
the XML schema in Appendix C. In May 2026 the IETF replaced RFC 7489 with three documents: [RFC 9989](https://www.rfc-editor.org/info/rfc9989/)
for DMARC itself, [RFC 9990](https://www.rfc-editor.org/info/rfc9990/) for aggregate reporting and
[RFC 9991](https://www.rfc-editor.org/info/rfc9991/) for failure reports. The structure is the same in both versions. Reports built to RFC 9990 use the XML namespace
`urn:ietf:params:xml:ns:dmarc-2.0` and can carry the new `np`, `testing` and `discovery_method` elements; reports
built to RFC 7489's schema can carry `pct`. A parser should accept both.

## Who sends them and how they arrive

A receiver that supports DMARC finds your reporting request when it looks up your DMARC record for incoming mail.
Without a `rua` tag it must not send aggregate reports at all
([RFC 9989, section 4.7](https://www.rfc-editor.org/info/rfc9989/)). You can list several addresses, separated by
commas, and a report should go to each. Yahoo's [sender best practices](https://senders.yahooinc.com/best-practices/)
strongly recommend a `rua` address for bulk senders; see
[Gmail and Yahoo sender requirements](https://email-validation.org/guides/gmail-yahoo-sender-requirements/).

RFC 9990, section 3.5.2, fixes the email format:

- The XML is attached, normally gzip-compressed (`application/gzip`, file ending `.xml.gz`), otherwise as `text/xml`.
- The file name joins the receiver, your domain and the start and end of the period, in seconds since 1970 (UTC),
  with `!` between them.
- The subject reads `Report Domain: <your domain> Submitter: <receiver>`, optionally with a `Report-ID:`.
- The report message must itself pass DMARC with alignment, which helps you discard forged reports.

A report covers one DMARC policy domain. Subdomains without their own `_dmarc` record appear as separate `record`
entries in the report for the parent domain; a subdomain with its own record gets its own report (RFC 9990,
section 3.1.2).

Expect volume. Google's [About DMARC reports](https://knowledge.workspace.google.com/admin/security/about-dmarc-reports)
says large organizations can receive hundreds or even thousands of reports a day, and recommends a dedicated group
or mailbox for them. RFC 9989 recommends parsing reports by machine rather than reading them by hand.

## The main elements

| Element | What it holds |
|---|---|
| `report_metadata` | Who sent the report (`org_name`, `email`), a unique `report_id`, the `date_range` (`begin`, `end`) and any `error` found in your record |
| `policy_published` | Your record as the receiver saw it: `domain`, `p`, `sp`, alignment modes `adkim` and `aspf`, and newer or older tags |
| `record` | One per combination of sending IP, results and identifiers; a report has at least one |
| `row` | `source_ip`, the message `count`, and `policy_evaluated` |
| `policy_evaluated` | The `disposition` applied (`none`, `quarantine`, `reject`, or `pass` in RFC 9990) and the DMARC verdicts for `dkim` and `spf`, plus an optional `reason` |
| `identifiers` | `header_from` (the From: domain), and optionally `envelope_from` and `envelope_to` |
| `auth_results` | Raw results: each `dkim` signature with `domain`, `selector` and `result`, and the `spf` check with `domain` and `result` |

The `date_range` marks the reporting period, not the first and last message, and RFC 9990 says it typically covers
one UTC day starting at 00:00.

## An annotated example

A shortened report for `example.com`, with documentation IP addresses:

```xml
<feedback xmlns="urn:ietf:params:xml:ns:dmarc-2.0">
  <report_metadata>
    <org_name>receiver.example</org_name>
    <email>dmarc-reports@receiver.example</email>
    <report_id>2026-11-05_example.com@receiver.example</report_id>
    <date_range><begin>1793836800</begin><end>1793923199</end></date_range>
  </report_metadata>
  <policy_published>
    <domain>example.com</domain>
    <p>none</p><sp>none</sp><adkim>r</adkim><aspf>r</aspf>
  </policy_published>
  <record>                                   <!-- 1: your own mail, fully aligned -->
    <row>
      <source_ip>192.0.2.25</source_ip><count>1840</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><selector>s1</selector><result>pass</result></dkim>
      <spf><domain>bounce.example.com</domain><result>pass</result></spf>
    </auth_results>
  </record>
  <record>                                   <!-- 2: a platform signing with its own domain -->
    <row>
      <source_ip>198.51.100.7</source_ip><count>312</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>
      <dkim><domain>platform.example</domain><selector>k1</selector><result>pass</result></dkim>
      <spf><domain>mail.platform.example</domain><result>pass</result></spf>
    </auth_results>
  </record>
  <record>                                   <!-- 3: forwarded copies -->
    <row>
      <source_ip>203.0.113.40</source_ip><count>6</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>example.com</domain><result>fail</result></spf>
    </auth_results>
  </record>
</feedback>
```

The period is 5 November 2026, 00:00 to 23:59:59 UTC. The receiver saw `p=none`, so nothing was quarantined or
rejected, whatever the results.

- **Record 1** passes both ways. The SPF domain `bounce.example.com` aligns with `example.com` under relaxed
  alignment (`aspf=r`), because both share the organizational domain.
- **Record 2** is the case to fix. Both raw checks pass in `auth_results`, but for the platform's domains, so neither
  aligns, and `policy_evaluated` shows `fail` twice. At `p=reject` these 312 messages would be at risk. Set up DKIM
  signing with your own domain at the platform, or a custom bounce domain.
- **Record 3** fails SPF because the mail arrived from a server not in your SPF record, but your DKIM signature
  survived, so DMARC still passes. This is the typical pattern of forwarding.

## How to read pass, fail and alignment

The key is the difference between the two blocks. `auth_results` holds the plain SPF and DKIM results, before DMARC
looks at alignment. `policy_evaluated` holds the DMARC verdicts: `pass` only if the check passed for a domain that
aligns with `header_from` (RFC 9990, section 3.1.1). DMARC passes if either verdict is `pass`.

| `auth_results` | `policy_evaluated` | Likely meaning |
|---|---|---|
| DKIM and SPF pass for your domain | `pass` / `pass` | Correctly set up |
| Pass, but for another domain | `fail` / `fail` | A service you use without alignment |
| DKIM passes for you, SPF fails | `pass` / `fail` | Forwarding; DMARC still passes |
| DKIM fails, SPF fails or another domain | `fail` / `fail` | A mailing list that changed the message, or a broken signature |
| No DKIM, SPF fails, unknown IP | `fail` / `fail` | Possible forgery, or a sender nobody told you about |

To identify a source IP, look up its PTR name (see [reverse DNS](https://email-validation.org/guides/reverse-dns-ptr/)) and compare it with the
services your company uses. The DKIM `selector` often points to the service too; see
[DKIM selectors and key rotation](https://email-validation.org/guides/dkim-selectors-key-rotation/). Look at counts: a few messages from an
unknown IP matter less than a steady stream.

## Forwarding and mailing list noise

Forwarders send your mail on from their own IP addresses, so SPF fails for those copies, while DKIM usually
survives. Mailing lists that add a subject tag or footer break DKIM as well
([RFC 7960](https://www.rfc-editor.org/info/rfc7960/), sections 2.2 and 3.2.3). Such rows will appear in your
reports with small counts from IP addresses you have never heard of. Do not add those IPs to your SPF record: they
are not yours, and aligned DKIM is the fix that carries through forwarding.

When a receiver applies something other than your policy, it can say why in `policy_evaluated/reason`. RFC 9990,
section 3.1.6, defines the types `local_policy`, `mailing_list`, `trusted_forwarder`, `policy_test_mode` (your
record has `t=y`) and `other`; RFC 7489 also had `forwarded` and `sampled_out` (excluded by `pct`). Google's report
page mentions accepting unauthenticated mail because it passed ARC as one such action.

## Sending reports to another domain

If the `rua` address is in a different organizational domain from your record, for example a report-processing
service, the receiver first checks that the destination agrees to take your reports
([RFC 7489, section 7.1](https://www.rfc-editor.org/info/rfc7489/); RFC 9990, section 4). It looks for a TXT record
named after your domain under `_report._dmarc` at the destination:

```text
_dmarc.example.com.                          TXT  "v=DMARC1; p=none; rua=mailto:dmarc@reports.example.net"
example.com._report._dmarc.reports.example.net.  TXT  "v=DMARC1"
```

The second record is published by the owner of `reports.example.net`. Without it, receivers ignore that address. A
destination willing to accept reports for any domain can publish a wildcard, `*._report._dmarc.reports.example.net`.
If you send reports to an address within your own organizational domain, no extra record is needed.

## Failure reports (ruf)

The `ruf` tag requests failure reports: one report per failing message, or per group of similar ones, sent soon
after the failure and carrying the message's header fields or even its full content
([RFC 9991](https://www.rfc-editor.org/info/rfc9991/), sections 1 and 2). The `fo` tag chooses when they are sent.

Expect few of them. Google's [Set up DMARC](https://knowledge.workspace.google.com/admin/security/set-up-dmarc) page
says Gmail does not support `ruf`, and RFC 9991, section 7, notes that many large providers limit or disable failure
reports because of privacy concerns. Aggregate reports are the dependable source.

## Privacy

Aggregate reports contain domain-level data: sending IP addresses, counts and authentication results. RFC 9990,
section 7.2, says they do not include individual email addresses or message content. Failure reports are different:
they may contain personal data from the message, and RFC 9991 recommends limiting their use to targeted diagnosis
and redacting content. If a third party processes your reports, it sees which services send your mail and how much;
RFC 9990, section 7.1, asks both domain owners and receivers to check whether their own policies permit that.

## Questions

### How soon do reports arrive after I publish a rua address?

Reports usually cover a full UTC day and are sent after it ends, so the first ones arrive after the first full day
with the record in place. Only receivers that support DMARC reporting and received your mail send one.

### Why do the counts not match what I sent?

Each receiver reports only the mail it received, and only receivers that send reports appear. Forwarded copies add
rows. Treat totals as a sample of your traffic, not an exact count.

### Do I need a paid service to read them?

No. RFC 9989, section 5.1.5, mentions both third-party services and your own tools; the XML is documented, so a
small domain can parse it with a script. Google suggests a service that specializes in DMARC, since it combines and
analyzes reports from many receivers.

## Try it

Check whether your record has a valid `rua` address with the [DMARC checker](https://email-validation.org/tools/dmarc-checker/), or write one
with the [DMARC generator](https://email-validation.org/tools/dmarc-generator/).

## Related

- [Glossary: SPF, DKIM and DMARC](https://email-validation.org/glossary/#spf-dkim-dmarc).
- [SPF checker](https://email-validation.org/tools/spf-checker/) and [DKIM checker](https://email-validation.org/tools/dkim-checker/) for fixing the sources a report
  reveals.
- Bounce code [5.7.32](https://email-validation.org/bounce-codes/5-7-32/): the From: domain is not aligned.

## Related guides

- [Moving DMARC from p=none to p=reject](https://email-validation.org/guides/dmarc-none-to-reject/)
- [Gmail and Yahoo sender requirements](https://email-validation.org/guides/gmail-yahoo-sender-requirements/)
- [DKIM selectors and key rotation](https://email-validation.org/guides/dkim-selectors-key-rotation/)
- [Reverse DNS (PTR records) for mail servers](https://email-validation.org/guides/reverse-dns-ptr/)
- [MTA-STS and TLS reporting explained](https://email-validation.org/guides/mta-sts-tls-rpt/)
- [All guides](https://email-validation.org/guides/)

## Sources

- [RFC 9990, DMARC Aggregate Reporting](https://www.rfc-editor.org/info/rfc9990/) (May 2026): XML elements, email
  format, external destinations, override reasons, privacy.
- [RFC 7489, DMARC](https://www.rfc-editor.org/info/rfc7489/) (March 2015): section 7.1 (external destinations),
  section 7.2 and Appendix C (the original report format).
- [RFC 9989, DMARC](https://www.rfc-editor.org/info/rfc9989/) (May 2026): the `rua` tag and report handling.
- [RFC 9991, DMARC Failure Reporting](https://www.rfc-editor.org/info/rfc9991/) (May 2026): failure reports and
  their privacy risks.
- [RFC 7960, Interoperability Issues between DMARC and Indirect Email Flows](https://www.rfc-editor.org/info/rfc7960/):
  why forwarding and lists break SPF and DKIM.
- [Yahoo: Sender best practices](https://senders.yahooinc.com/best-practices/): the `rua` recommendation.
- [Google Workspace: About DMARC reports](https://knowledge.workspace.google.com/admin/security/about-dmarc-reports):
  report volume, dedicated mailbox, ARC overrides.
- [Google Workspace: Set up DMARC](https://knowledge.workspace.google.com/admin/security/set-up-dmarc): Gmail does
  not support `ruf`.

## Get up to 500 free credits. No card needed.

New accounts get 500 free credits (100 when you sign up with a free email provider such as Gmail, Outlook or Yahoo, or another personal mailbox such as a paid one like Fastmail or one from your internet provider). Try it on your own list before you buy. [Create your account](https://email-validation.org/signin/?new=1) or [open the free email checker](https://email-validation.org/email-checker/).
