Blog · Dmarc

DMARC Aggregate Reports and RFC 9990 Compliance: What Changed and What It Means for Your Monitoring

You have been receiving DMARC aggregate reports for months. Maybe years. If you have ever opened the XML file and felt lost in a maze of ``, ``, and `` tags, you are not alone. And if you recently heard that RFC 9990 changed something, you may be wondering whether your monitoring setup is now outdated.

It probably is not. But there are specifics worth knowing.

This article explains what DMARC aggregate reports contain, what RFC 9990 changed from the older RFC 7489, and what to look for in your own reports to confirm your DMARC policy is working the way you expect. If you are tired of opening XML files by hand, DMARCFlow can decode these reports automatically and surface the signal without the noise.

---

What Is a DMARC Aggregate Report

When you publish a DMARC record with a `<`_dmarc.example.com>` DNS entry that includes a `rua` tag pointing to an email address or webhook, participating mail receivers send you aggregate reports on a schedule they choose. Daily is common. Some send more frequently.

The report is an XML file. It is not human-readable by design - it is meant to be processed by a machine. The file tells you, in structured form, what messages the receiver encountered that claimed to be from your domain, and what the receiver concluded about those attempts.

Think of it as a daily snapshot of every mail server on the internet that tried to deliver mail as you - and what each receiver observed about those attempts.

---

What the XML Report Actually Contains

Here is a plain-language map of the key elements in a DMARC aggregate report.

report_metadata

The header section. Contains the report generator is identifier, the reporting period (start and end timestamps), and the report ID. Useful for tracking which report you are looking at.

policy_evaluated

What the receiver decided to do with a message. It contains:

  • `disposition`: none, quarantine, or reject
  • `dkim`: pass or fail
  • `spf`: pass or fail

The disposition field tells you whether the message was delivered normally, sent to spam, or rejected based on the receiver is DMARC evaluation. It does not account for other filtering the receiver may apply afterward.

auth_results

The detailed authentication data. For each message or batch of messages, this section records:

  • `dkim`: the domain that was checked, the result (pass or fail), and whether the signature was aligned with your From domain
  • `spf`: the domain that was checked, the result, the sender IP, and whether it was aligned

Alignment matters. A DKIM signature can pass but still fail DMARC if the signing domain does not match your From domain. The aggregate report shows you both the raw authentication result and the alignment result.

source_type

How the receiver discovered the DMARC policy. Usually this is "mail_from" - meaning the receiver looked at the RFC 5321 MAIL FROM domain.

---

The RFC 9989 / RFC 9990 / RFC 9991 Trio

Before getting into what RFC 9990 changed, it helps to understand how the three relevant RFCs relate.

  • RFC 9989 is the core DMARC specification. It defines the `<`_dmarc.example.com>` DNS record format, the `p=` policy tag, the `rua` and `ruf` reporting tags, alignment requirements, and the overall DMARC mechanism. It is the current standards track DMARC base protocol.
  • RFC 9990 is the aggregate reporting specification. It defines the XML schema for aggregate reports, what data they must and may contain, delivery requirements, and how report consumers should interpret them. It is the standards track document that obsoleted RFC 7489 is aggregate reporting provisions.
  • RFC 9991 covers failure reporting, sometimes called forensic reports or RUF reports. It defines the format and delivery of per-message failure reports.

RFC 9990, together with RFC 9989 and RFC 9991, formally replaced the original RFC 7489 as the current DMARC standards track. The practical takeaway: if you are operating DMARC today, your DNS records, your authentication logic, and your aggregate reports all trace back to these three documents. RFC 9990 is the one that tells you what your daily XML files are supposed to contain.

---

What RFC 9990 Changed from RFC 7489

RFC 9990 is a full revision of the DMARC aggregate reporting specification, not a set of minor edits. Here are the key areas where it differs from RFC 7489.

Policy domain handling clarified

RFC 9990 makes explicit how multi-domain operators should interpret the `domain` element in the report. The distinction between the policy domain (the domain that published the DMARC record) and the organizational domain (the parent domain that shares the same organizational boundary) is now described in more detail. This matters if you manage DMARC across a large domain portfolio - the report may show failures for subdomains you did not expect.

DKIM signature reporting updated

The way DKIM signatures are reported changed. Under RFC 9990, receivers now report DKIM signatures more granularly, distinguishing between signatures that cover specific header fields. This was ambiguous in RFC 7489. The practical effect: if you are running multiple DKIM signers (for example, different ESPs signing different header combinations), aggregate reports under RFC 9990 give you clearer data about which signatures passed or failed.

Error element introduced

RFC 9990 formalizes an error element for situations where the receiver encountered an issue parsing or processing a message is authentication data. This did not have a designated field in RFC 7489. The error element gives report consumers a way to distinguish between a message that genuinely failed authentication and one where the authentication data was malformed or incomplete.

Policy override reasons expanded

RFC 9990 expands and formalizes the `` element. In RFC 7489, override reasons were optional and loosely defined. RFC 9990 provides a more structured list of valid reasons - for example, `mail_policy_discretionary`, `domain_owner_policy`, or `some_other_reason`. This matters for operators trying to understand why a message that should have been rejected was instead accepted.

Handling of policy changes during the reporting period

If a domain owner changed their DMARC policy during the reporting window (for example, moving from `p=none` to `p=reject` mid-day), RFC 9990 specifies how receivers should handle that in the aggregate data. RFC 7489 was silent on this. RFC 9990 states that if multiple policy configurations were observed, the receiver MAY send multiple reports or MAY record only the final configuration. Check your report generator is documentation to understand how it handles this edge case.

---

Policy Domain vs Organizational Domain: Why the Distinction Matters

This is one of the most common sources of confusion in aggregate reports.

The policy domain is the domain that published the DMARC record. If you have `<`_dmarc.example.com>` with `p=reject`, your policy domain is `example.com`.

The organizational domain is the registered domain at the top of the DNS hierarchy. For `sub.example.com`, the organizational domain is still `example.com`. DMARC uses the organizational domain to determine alignment: a DKIM signature from `sub.example.com` is considered aligned with the organizational domain `example.com`.

In your aggregate report, you will see the policy domain in the `` field of each record. If you manage multiple brands or business units under one registered domain, you may have separate DMARC records for each subdomain, but they share the same organizational domain for alignment purposes.

The practical implication: a DMARC failure for `sub.example.com` in your report does not necessarily mean `example.com` is misconfigured. It may mean the subdomain is sending mail without proper authentication. Aggregate reports break down by policy domain precisely so you can tell the difference.

---

What to Look for in Your Aggregate Reports

If you have a DMARC monitoring setup, here is a practical checklist for reviewing your aggregate reports.

Are aligned authentications present?

Both DKIM and SPF should show aligned passes for your legitimate mail. If you see consistent DKIM fails for traffic you know is legitimate, check whether your DKIM signing domain matches your From domain. Many ESPs sign from their own domain, not yours - which means those messages rely on SPF alignment instead.

Are failed alignments legitimate?

A failed alignment does not always mean something is broken. It may mean a third party is sending mail on your behalf without proper authentication. That is exactly what DMARC is designed to surface. If the sending IP belongs to a vendor or partner, you need to decide whether to authorize them via SPF or a third-party DKIM arrangement.

Is disposition matching your policy?

If you set `p=quarantine` but you see messages with `disposition=none`, the receiver processed them outside of DMARC - likely because other signals triggered normal delivery before DMARC evaluation applied its policy. This is normal and does not indicate a DMARC failure.

If you set `p=reject` but see `disposition=none`, check whether the report shows a policy override reason (such as `mail_policy_discretionary`). Some receivers apply local discretion and override a `p=reject` policy in specific circumstances - and RFC 9990 now requires them to report that override reason more explicitly.

Are policy override reasons present?

If you see `policy_override_reason` values, look at what they say. `mail_policy_discretionary` means the receiver applied local policy discretion to override your stated policy. This is not a DMARC failure, but it is worth knowing about - it means the receiver did not fully enforce your policy.

---

Does RFC 9990 Compliance Matter for Report Consumers

For most operators, the answer is: not immediately, but monitor your tooling.

If you are using a third-party DMARC monitoring service, the burden of RFC 9990 compliance falls primarily on the receiver side - mail receivers generate the reports. On the consumer side, your monitoring tool needs to parse the XML correctly and surface the relevant fields.

If your monitoring tool is manually parsing XML or using a home-grown script, check whether it handles the new elements RFC 9990 introduced, particularly the error element and the expanded policy override reasons. Most modern DMARC monitoring services have already updated their parsers.

If you are relying on receivers to send reports correctly: RFC 9990 compliance is not mandatory for receivers yet in the sense that they will be cut off from sending. But the IETF standards track means RFC 9990 represents the current agreed specification, and receivers that have updated their systems will be producing reports in the new format.

---

Stop Parsing XML by Hand

Reading DMARC aggregate reports by hand is slow and error-prone. The XML format is dense, and RFC 9990 has added new elements that make manual parsing even more complex.

DMARCFlow automatically receives and parses your aggregate reports, surfaces the key fields, and alerts you when something in your authentication posture changes. You do not need to open an XML file to know whether your aligned DKIM is passing or whether a new sending domain is generating unexpected failures.

Set up your `rua` tag to point to DMARCFlow and you will receive plain-language summaries of each report - organized by domain, by date, with the RFC 9990 fields decoded and the signal separated from the noise.