RFC 9990 — DMARC aggregate reporting

Domain-Based Message Authentication, Reporting, and Conformance (DMARC) Aggregate Reporting

Status
Proposed Standard
Published
2026
Obsoletes
RFC 7489

RFC 9990 defines the DMARC aggregate report — the XML document that arrives at whatever address your rua= tag points to. It was split out of RFC 7489 alongside RFC 9989 (the protocol) and RFC 9991 (failure reports).

If you are writing or debugging anything that parses these reports, this is the document to cite now, not RFC 7489.

Why it was split out

The RFC says so directly: separating the pieces “allows these pieces to potentially be altered in the future without re-opening the entire document, as well as allowing them to move through the IETF process independently.”

The report format changes on a different clock from the protocol. Now it can.

Why the reporting half is the important half

It is tempting to read reporting as an accessory to the policy. The history says otherwise. DMARC had a predecessor — ADSP, now formally Historic — which let a domain declare that unsigned mail should be discarded, and which almost nobody deployed.

The reason is that ADSP had no reporting. A domain owner could publish the strict setting, but had no way to find out what it would break beforehand, so publishing it was a gamble nobody sensible took. DMARC’s contribution was not a better policy language; it was making the policy safe to adopt by letting you watch first. That is what this document specifies, and it is why starting at p=none and reading reports is the whole method rather than a cautious optional step.

What is in a report

The structure is unchanged in outline — a <feedback> root containing:

Element
report_metadatarequiredWho generated it, a report ID, and the date range
policy_publishedrequiredThe DMARC record as the receiver read it
recordrepeatedOne per sending source: counts, disposition, and the SPF/DKIM results
extensionoptionalNew — room for future data without breaking parsers

Our guide to reading a DMARC aggregate report walks through a real one field by field.

What changed from RFC 7489

The RFC’s own list of the differences that matter:

  • The XSD has been clarified throughout, so report structure should be more consistent between receivers. In practice this was a real problem — the old schema left enough latitude that reports from two providers could both be valid and still need different parsing.
  • The report identifier has more structure.
  • The number of domains per report is clarified.
  • Extensions are now part of the report structure, so new data can be added without breaking existing parsers.
  • PSD reporting is part of the specification, rather than the separate experiment it was under RFC 9091.
  • The selector is now required when reporting a DKIM signature.

That last one is quietly the most useful change for anyone operating DMARC. A DKIM result without a selector tells you a signature failed but not which key — and with several services signing for one domain, that is the difference between a report you can act on and one you cannot. It is now mandatory.

What it means in practice

Nothing to publish and nothing to change. This is a document about the reports you receive, not the record you serve.

If you self-host report processing, the useful consequence is that reports should get more consistent as receivers implement RFC 9990, and DKIM failures should become attributable to a specific selector rather than a guess. That is what DMARC Analyzer does with them — parsed, grouped per client domain, on your own infrastructure with no per-domain fee.

Read it: rfc-editor.org/rfc/rfc9990