Envello
Deliverability

How to read a DMARC aggregate report

Envello Team·2026-07-30·6 min read

Once you publish a DMARC record with an rua= address, mailbox providers start emailing you gzipped XML files, usually once a day per provider. Opening the first one is where most people give up: it's machine-readable, not human-readable, and there's no built-in explanation of what any of it means. This is what each field is telling you and how to read the report without a paid tool.

The structure: policy, then a list of records

Every aggregate report has two parts. A <policy_published> block echoes back your own DMARC record, the domain, policy, and alignment mode, so you can confirm the sender received what you actually published. Then a series of <record> blocks, one per sending source the receiver saw claiming to be from your domain during the reporting window, usually 24 hours.

Each <record> is the unit that matters. It tells you: which IP sent mail as your domain, how many messages, what the receiver did with them, and whether SPF and DKIM passed.

source_ip and count: who sent what, how often

<source_ip> is the sending server's IP address. <count> is how many messages that IP sent claiming your domain during the window. Cross-reference the IP against your known senders: your transactional email provider's documented sending ranges, your marketing platform, any internal tool. An IP you don't recognize sending a handful of messages is usually not fraud, it's a forgotten integration or a legitimate sender using infrastructure you didn't map. An unrecognized IP sending thousands is the pattern worth investigating.

disposition: what actually happened to the mail

<disposition> is what the receiving server did based on your policy: none (delivered normally), quarantine (sent to spam), or reject (blocked outright). This only reflects what your published policy told receivers to do, it's not a judgment call the receiver made independently. If you're on p=none, disposition will always read none regardless of whether SPF/DKIM passed, because none means monitor-only.

SPF and DKIM results: alignment, not just pass/fail

Inside <auth_results>, both <spf> and <dkim> report a result (pass or fail) for that specific message. But the field that actually determines DMARC compliance is alignment, whether the domain in the SPF or DKIM check matches the domain in the visible From: header, not just whether SPF or DKIM passed in isolation.

A message can pass SPF against the return-path domain (often a subdomain your ESP controls) while failing SPF alignment against your From: domain. This is the single most common cause of confusing reports: SPF says pass, DMARC still fails, because alignment failed even though authentication succeeded.

What to actually do with a report

Read reports for at least a full week before drawing conclusions, single-day spikes are common and often meaningless. Build a list of every source_ip that shows consistent passes across multiple days, that's your legitimate sender list. Anything failing consistently and unrecognized is worth investigating; anything failing once is noise. This report-reading discipline is what the p=none stage of a DMARC rollout is actually for, see our guide on moving from p=none to p=reject for the full staged process once your reports are clean.

Envello

EU-hosted transactional email, done right by default.