Guides

How to read a DMARC aggregate XML report

18 October 2026

An aggregate DMARC report is the XML file mailbox providers send to the address in your rua tag. It counts messages that used your From domain, with the authentication result and the policy that applied. It is not a copy of each message, and it is not an inbox-placement test.

What arrives in the mailbox

RFC 7489 section 7.2 describes the report. If rua is missing, receivers must not generate aggregate reports. When it is present, the usual transport is email. The XML should be gzip-compressed, with a filename shaped like receiver!example.com!begin!end.xml.gz. The timestamps are seconds since 1970-01-01 UTC. The subject line should look like Report Domain: example.com Submitter: mail.receiver.example Report-ID: ….

Receivers must be able to send daily reports. The default interval (ri) is 86400 seconds. Anything more frequent is best-effort. Reports are easier to line up when each one starts at 00:00 UTC, which the RFC asks generators to do for a 24-hour period.

The message carrying the report is itself supposed to pass DMARC with an aligned pass. That is there so you are less likely to process a report someone forged. It is a check on the report mail, not a promise about your own campaigns.

The three parts of the XML

The schema in Appendix C puts the document under a feedback element. Three children matter for a first reading.

report_metadata

Who produced the file, and which hours it covers.

policy_published

The DMARC policy the receiver found for the domain, not a guess about what you wish you had published.

If you changed the TXT record during the reporting window, a single file can still contain one policy_published element while the rows reflect a mix of the old and new policy. The RFC tells consumers to expect that. Sort by date range before you conclude the receiver ignored an edit.

record, and the row inside it

Each record is a group of messages that shared a result. It has three children.

row holds:

identifiers holds header_from (the domain in the From header) and envelope_from (the MAIL FROM domain). envelope_to is optional.

auth_results holds the raw checks:

Read auth_results and policy_evaluated as a pair. A raw SPF pass on a domain that does not align shows up as auth_results/spf/result of pass and policy_evaluated/spf of fail. That combination is the whole alignment story in one row.

Unauthorized source, or a legitimate sender set up wrong

Use source_ip, the raw results, and whether you recognize the sender. The count tells you whether it is a trickle or your actual mail.

Unauthorized

The IP is not one you or your providers operate. header_from is your domain. Raw SPF is fail, softfail, or none, and DKIM is none or fail. Both policy_evaluated results are fail. Nobody authorized that host, and nobody signed as you.

With p=none, disposition can still be none. You asked for no specific action, so a failure row with disposition none is expected. It means the receiver recorded the failure. It does not mean the message was legitimate. That is the reason to stay on p=none until these rows are ones you understand, and then move toward quarantine or reject.

A legitimate sender, misconfigured

You know the IP, or the dkim/domain and selector match a provider you pay. The raw check may even pass, on the wrong name.

A reason of forwarded or mailing_list means the receiver overrode the published policy for a message that was altered in transit. Read it before you decide the sender is hostile. Forwarding and lists break DKIM and SPF in ways your DNS cannot prevent.

Forensic reports (ruf), briefly

Section 7.3 describes failure reports, requested with the ruf tag. They are meant to go out soon after a DMARC failure, in the authentication-failure format the rf tag names (AFRF by default). They can include headers and URIs from the failed message, which is why they are more sensitive than a daily count. The fo tag asks when to send one. The default, 0, is when every underlying mechanism failed to produce an aligned pass. fo is ignored if ruf is absent.

If you do not publish ruf, receivers must not send failure reports. If you do, a receiver sends them only when it is willing. The same section notes that an attacker can forge your domain, fail authentication on purpose, and try to flood the ruf mailbox. Aggregate rua reports cover mail that passed and mail that failed, without a copy of each message. Read those first.

Sources