The DMARC Aggregate Report, Dissected: XML Anatomy, Senders, and the RFC 9990 Schema
A DMARC aggregate report is a compressed XML file that a receiving mail provider emails to the rua= address in your DMARC record, summarizing the SPF, DKIM, and DMARC results for every message that claimed your domain during one UTC day. The format is defined in RFC 9990 — the DMARCbis aggregate reporting specification, published May 2026 as a Standards Track document that, together with RFC 9989 and RFC 9991, obsoletes RFC 7489.
If one of these landed in your inbox: your own DNS asked for it. Google, Microsoft, Yahoo, Mail.ru, Fastmail, Zoho, and other receivers send one report per UTC day, and the first usually arrives 24–48 hours after you publish rua=mailto: in your DMARC record. It is normal, and it is the feedback loop DMARC was designed around — not an attack. Just want to know whether the email in your inbox is safe? Jump straight to is this report legitimate.
553,586 of 937,931 DMARC-enabled domains (top 1.8M) had a rua= tag configured in 2026 — the other 41% publish a policy and collect nothing back
This post dissects the report object itself: a full annotated RUA XML file, a sender-by-sender cadence table with sourcing labels, the element-level schema diff RFC 9990 introduced, and how to tell a real report from a fake. Every schema claim below cites an RFC 9990 section or appendix directly. When you want the other half — how to read and act on each field once you have the file open — that walkthrough is its own guide.
What does a real RUA XML sample look like, annotated?
Here is a complete, realistic DMARC aggregate report sample in the shape you will actually receive today — the legacy RFC 7489 form that Google-style generators still emit, with <pct> present and no XML namespace. All names are synthetic.
<?xml version="1.0" encoding="UTF-8"?>
<feedback>
<report_metadata>
<org_name>Example Mail Receiver</org_name>
<email>[email protected]</email>
<report_id>8267341290173392847</report_id>
<date_range>
<begin>1755993600</begin>
<end>1756079999</end>
</date_range>
</report_metadata>
<policy_published>
<domain>yourdomain.example</domain>
<adkim>r</adkim>
<aspf>r</aspf>
<p>none</p>
<sp>none</sp>
<pct>100</pct>
</policy_published>
<record>
<row>
<source_ip>203.0.113.25</source_ip>
<count>412</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
<identifiers>
<envelope_from>yourdomain.example</envelope_from>
<header_from>yourdomain.example</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>yourdomain.example</domain>
<selector>mail2026</selector>
<result>pass</result>
</dkim>
<spf>
<domain>yourdomain.example</domain>
<result>pass</result>
</spf>
</auth_results>
</record>
</feedback> Before the XML even opens, the envelope follows conventions worth knowing. The email subject must match the ABNF in RFC 9990 §3.5.2: Report Domain: yourdomain.example Submitter: reporter.example Report-ID: <id>. The attachment filename is bang-separated per the same section: receiver!policy-domain!begin-timestamp!end-timestamp.xml.gz — for example, reporter.example!yourdomain.example!1755993600!1756079999.xml.gz. Both patterns are legitimacy signals we will use later.
Inside, every aggregate report follows the same fixed element order (RFC 9990 §3.1.1.2). Walking the sample above by its own values, top to bottom:
report_metadata—org_namenames the generator (“Example Mail Receiver”),report_id8267341290173392847uniquely identifies this file, and thedate_rangepair1755993600–1756079999is Unix time for exactly one UTC day: 00:00:00 to 23:59:59 on 2025-08-24. RFC 9990 §3.1.1.3 adds an optionalgeneratorelement naming the reporting software and version.policy_published— the DMARC policy this receiver discovered in your DNS during the window (RFC 9990 §3.1.1.5):p=nonewith relaxed DKIM and SPF alignment (adkim=r,aspf=r) applied to 100% of mail (pct=100, a legacy-only tag). If this block differs from what you think you published, the receiver saw stale or different DNS.record→row— the payload. One source, IP203.0.113.25, sent 412 messages (count) during the day, andpolicy_evaluatedrecords the DMARC verdict for all of them:dispositionisnonebecause the published policy isp=none, and bothdkimandspfevaluated as aligned passes (RFC 9990 §3.1.1.10–3.1.1.11).record→identifiersandauth_results—header_fromis the domain DMARC actually judged (yourdomain.example), andauth_resultsholds the raw outcomes behind the verdict: a DKIM pass signed with selectormail2026— the selector field RFC 9990 §3.1.1.12 now makes required — and an SPF pass for the same domain (§3.1.1.13).extension— absent from this legacy-shaped sample. New in RFC 9990: an optional slot for namespaced extension elements at file level, with a matching slot at record level (RFC 9990 §5).
Reports are GZIP-compressed XML. RFC 9990 §3.5.2 requires the compression precisely because an uncompressed report can exceed a receiver’s SMTP size limit — though in practice the files are tiny. Measured per-provider report sizes ran 3.6–4.8 KB (Google 3,962 bytes, Yahoo 4,626, Fastmail 4,839 — Ashiq et al., USENIX Security, 2023 data).
7 domains received 43% of all DMARC aggregate reports on behalf of domain owners as of January 2023 — most owners point rua= at a processing service, not a human mailbox
One experience note from our side: when we built DMARCguard’s parser, we made it namespace-agnostic. RFC 7489 reports carry http://dmarc.org/dmarc-xml/0.1 — or, very often, no effective namespace at all — while RFC 9990 reports declare urn:ietf:params:xml:ns:dmarc-2.0. A parser keyed to either one silently drops the other, so we accept both and key on structure instead. The full walkthrough of what each DMARC policy field means for your next action is in the reading guide linked above.
Our own scan data shows how few domain owners ever see one of these files at all: most publish a policy without the rua= tag that requests the feedback.
16.3% of domains DMARCguard scans with a working DMARC record publish a working rua= URI — the other 83.7% have enforcement on and telemetry off
Who sends DMARC aggregate reports, and how often?
Any DMARC-implementing receiver that got mail claiming your domain can send one. In practice, six senders account for most of what lands in a rua= mailbox. Cadence and addresses below are labeled official or community-sourced, because several providers never documented their own behavior — a gap most explainers paper over.
| Receiver | Cadence | Reporter address | Format | Sends RUF? |
|---|---|---|---|---|
| Daily — “usually sent once a day” (official, updated 2026-07-22) | [email protected] (official example XML) | .zip/.gz XML | Not documented | |
| Microsoft 365 | Daily, covering the previous day (official, updated 2026-05-14) | [email protected] (community-observed) | GZIP XML (official) | No — official: Microsoft 365 doesn’t send failure reports even with a valid ruf= |
| Yahoo / AOL | Not documented officially | [email protected] (community-captured) | Not documented | Not documented — Sender Hub FAQ describes DMARC but not Yahoo’s own reporting behavior |
| Mail.ru | Daily (official, updated 2025-09-08) | [email protected] (official) | .gz XML (official) | No |
| Fastmail | Not documented | [email protected] (community-captured) | XML | No — Fastmail-authored setup text: aggregate only, no plans for ruf |
| Zoho | Daily per Zoho’s general RUA description; own cadence not documented | [email protected] (community-captured, 2021 — may have drifted) | XML attachment | Not documented |
Reporter addresses drift and are mostly undocumented — only Google and Mail.ru state theirs officially — so never hard-code an allow-list to a single address.
Timing. The reporting period “will encompass a single UTC day, beginning at 0000UTC” (RFC 9990 §3.1.1.4), and reports are sent after the window closes. That is why the first report takes 24–48 hours: publish rua= at 08:00 UTC and collection only starts at the next UTC midnight. Community measurements from dmarcian, GlockApps, and DMARC Advisor — platforms observing report timestamps at scale — put worst-case first-report latency around 38 hours for low-volume domains.
Who will never write to you. Apple/iCloud and Proton are not documented as sending aggregate reports, and admin observation backs the absence. Microsoft’s own guidance sets the expectation plainly: “Not all receivers send reports. Coverage is typically 70-90% of total mail volume” (Microsoft Learn, 2026-05-14). No official source publishes a numeric minimum-volume threshold below which reports stop — the only documented condition is functional: no observed mail claiming your domain, no report.
Why volume exploded in 2024. The February 2024 Google/Yahoo bulk-sender mandate forced every 5,000-plus-message sender to publish DMARC, and millions of new rua= endpoints came online — and millions of inboxes started receiving XML their owners never expected.
265 billion fewer unauthenticated messages sent to Gmail in 2024 after the bulk-sender mandate
Aggregate RUA reports are one of two DMARC feedback channels. The other, per-message failure reports (RUF), uses the ARF format and a different RFC entirely — what ARF failure reports contain is its own topic, and as the table shows, most major receivers simply don’t send them.
What did RFC 9990 change in the report schema?
RFC 9990, together with RFC 9989 (core protocol) and RFC 9991 (failure reporting), obsoletes and replaces RFC 7489 (RFC 9990 §2). The old single document was split three ways so each part can evolve independently. Most vendor documentation — Microsoft Learn included — still points readers at “RFC 7489 Appendix C” for the report schema. The current Standards Track schema is RFC 9990 Appendix A, and its own Appendix C enumerates six differences from RFC 7489:
- The XSD was clarified — explicit multiplicity and typed enums, so different generators produce more consistent XML.
- The report identifier has more structure — Report-ID now has a formal ABNF (RFC 9990 §3.5.1) instead of a bare message-id.
- One domain per report — each report MUST cover exactly one DMARC Policy Domain and one policy configuration.
- Extensions — reports may carry namespaced
extensionelements at file and record level. - PSD is in the specification — Public Suffix Domain reporting and its privacy considerations are folded in.
- DKIM
selectoris now required — it was optional in RFC 7489.
In practice only one of those six can break an existing setup — the required DKIM selector — so read the table that follows as a checklist, not a threat. For most senders nothing breaks except the DKIM selector field; every other change is additive or relaxing. Element by element, verified against both schemas (RFC 7489 Appendix C XSD vs RFC 9990 Appendix A XSD):
| Element | RFC 7489 | RFC 9990 | Change | What it means for you |
|---|---|---|---|---|
| XML namespace | http://dmarc.org/dmarc-xml/0.1 | urn:ietf:params:xml:ns:dmarc-2.0 | Changed (Appendix A) | Any parser you run must accept both namespaces |
pct in policy_published | Required | Removed | Removed (§3.1.1.5) | Stop treating a missing pct as a malformed file |
DKIM selector | Optional | Required | The one hard break (§3.1.1.12) | Fix any generator or parser that drops selector |
discovery_method, np, testing | Absent | Optional in policy_published | Added (§3.1.1.5) | Extra context when present; safe to ignore |
generator | Absent | Optional in report_metadata | Added (§3.1.1.3) | Tells you which software produced the report |
extension blocks | Absent | File level + record level | Added (§5) | Ignore unknown blocks — never reject the report |
envelope_from, version, sp, spf | Required | Optional | Relaxed | Do not require these fields to accept a report |
reason/type enum | Includes forwarded, sampled_out | Both dropped; policy_test_mode added | Changed (§3.1.6) | Update any enum allow-lists in strict validators |
disposition (evaluated) | none/quarantine/reject | Adds pass | Widened (Appendix A) | Handle pass as a valid disposition value |
SPF scope | helo/mfrom | mfrom only | Narrowed (§3.1.1.13) | Expect mfrom only in new-shape reports |
| Report-ID | Bare msg-id | Formal ABNF, optional in the Subject line | Structured (§3.5.1) | Subject-line parsing may meet a structured ID |
Read as a whole, the diff is overwhelmingly additive or relaxing. With the single exception of the DKIM selector becoming required, nothing that parsed before breaks after. The operational risk runs the other way: a strict RFC 7489 validator will reject valid new-shape reports — pct is gone, envelope_from and version may be absent, and the namespace differs, so namespace-keyed validators silently fail to match. RFC 9990 §5 settles the posture: a processor that cannot handle an extension “SHOULD ignore the data and continue.” Tolerant parsing is now the specified behavior, not a workaround.
For contrast, here is what a spec-shaped RFC 9990 fragment looks like — labeled clearly, because no major provider emits this yet:
<!-- Spec-shaped example per RFC 9990 Appendix A/B —
no major provider emits this shape yet. -->
<feedback xmlns="urn:ietf:params:xml:ns:dmarc-2.0">
<version>1.0</version>
<report_metadata>
<org_name>Example Mail Receiver</org_name>
<email>[email protected]</email>
<report_id>3v98abbp8ya9n3va8yr8oa3ya</report_id>
<date_range>
<begin>1755993600</begin>
<end>1756079999</end>
</date_range>
<generator>Example DMARC Aggregate Reporter v1.2</generator>
</report_metadata>
<policy_published>
<domain>yourdomain.example</domain>
<p>quarantine</p>
<np>none</np>
<testing>n</testing>
<discovery_method>treewalk</discovery_method>
</policy_published>
<!-- extension and record elements follow -->
</feedback> That “not yet” matters. Google’s own example report in its Admin Help — page last updated July 2026 — is still legacy-shaped, <pct> and all. Microsoft Learn still cites RFC 7489 Appendix C as the schema. And URIports, an independent processor that began validating incoming reports against RFC 9990 in June 2026, confirms senders still ship legacy and incomplete reports. Plan for a multi-year mixed-shape window: treat the 2015 schema as the floor and RFC 9990 fields as enrichment when present. The record-tag side of DMARCbis — pct, rf, and ri removal, the DNS tree walk — is covered in what changed across the full DMARCbis set.
”Find attached the DMARC aggregate report”: is it legitimate?
Almost certainly yes — and receiving it is desirable, not a problem. But the confusion is real and recurring. A recipient on Microsoft Q&A in December 2023: “I don’t understand what is wanted from me, why and what I should do.” The same question resurfaces in Shopify, Zoho, and Cisco communities every quarter, usually from someone whose predecessor published the DMARC record.
Five checks separate a genuine report from a phish dressed up as one:
- Match the sender against a documented reporter address. Use the table above —
[email protected],[email protected],[email protected], and peers. If the sender is nothing your domain’s mail could plausibly have reached, be suspicious. - Check the subject against the RFC 9990 §3.5.2 pattern. A genuine report reads
Report Domain: <your-domain> Submitter: <reporter-domain> Report-ID: <id>. This exact “Report Domain: … Submitter: …” pattern is probably what brought you here — it is the standard, not a scam template. - Inspect the attachment. Expect inert compressed XML with the bang-separated filename (
receiver!your-domain!begin!end.xml.gz). A.exe,.html,.js, or macro-enabled document is the red flag — never the XML itself. - Confirm the report email passes its own authentication. Open the headers (Show original in Gmail) and check for SPF, DKIM, and DMARC passes. RFC 9990 §3.5.2 requires report mail streams to produce an aligned DMARC pass, so a failing report email deserves suspicion. Note the direction of the rule: it binds the sender’s mail stream — for you as recipient it is a strong heuristic, and RFC 9990’s recipient-side protection is the DNS authorization in §4, not this header check.
- Look for what real reports never contain. No links to click, no payment demands, no credential requests, no expiry warnings. A genuine aggregate report is machine data only.
If you want the reports to stop, do not just delete them from your inbox — edit DNS. Removing the rua= tag ends the reports but blinds you to spoofing attempts against your domain; re-pointing rua= at an analyzer keeps the visibility without the clutter. If the new destination is on a different domain, that domain must publish the authorization record RFC 9990 §4 requires — a TXT record at <policy-domain>._report._dmarc.<receiver-domain> containing v=DMARC1; — or receivers will silently stop sending. And if the reports show your legitimate mail failing through a gateway such as Mimecast, that has a specific fix: why DMARC fails behind Mimecast and how to fix it.
FAQ
Why am I getting a DMARC aggregate report?
Your domain’s DMARC TXT record contains a rua=mailto: address that points at (or forwards to) you. Most major receivers that saw mail claiming your domain send a daily summary to that address (RFC 9990 §1; Google Workspace Help) — coverage is broad but not universal, as the sender table above shows. It is not spam and not an attack — your own DNS requested it.
Who sends DMARC aggregate reports?
Receiving mail providers — “Mail Receivers” in RFC 9990 §3.1. In practice: Google ([email protected]), Microsoft 365 ([email protected]), Yahoo, Mail.ru, Fastmail, and Zoho. Apple/iCloud and Proton are not documented as report senders, so expect no reports from them regardless of configuration.
How often are DMARC aggregate reports sent?
Once per day per reporting provider, covering a single UTC day beginning at 0000 UTC (RFC 9990 §3.1.1.4). You receive one report from each provider that saw your mail — Google notes large senders can receive hundreds daily. The first report typically arrives 24–48 hours after you publish rua=.
What triggers a DMARC report?
A valid rua=mailto: URI in your DMARC record, plus mail that a receiver observed claiming your From domain. No rua= tag means no reports — RFC 9989 states receivers MUST NOT generate aggregate feedback without it. Reports can list mail you never sent; that is spoofing or forwarding being surfaced to you.
How do I read a DMARC aggregate report?
Extract the .gz or .zip attachment, open the XML, check policy_published for the policy the receiver saw, then walk each record for the source IP, message count, and SPF/DKIM alignment results. The full field-by-field walkthrough is covered in our reading guide, linked in the introduction.
The report object, settled
A DMARC aggregate report is a once-per-UTC-day XML summary of everything that claimed your domain, sent because your rua= tag asked for it. The senders and cadences above are documented where documentation exists — and labeled where it doesn’t. RFC 9990 is now the schema’s source of truth, but every major generator still emits the legacy shape, so the practical posture is tolerant parsing: both namespaces, no hard-required pct, unknown elements ignored.
The XML is only step one; choosing what processes it is where the workflow starts, and we compared the field in best DMARC reporting tools. Or skip straight to the data you already have: paste a report into DMARCguard’s free DMARC report analyzer — no signup required — and see it decoded record by record.