Quick answer
A DMARC aggregate report is a daily XML file from each major mailbox provider naming every server that sent mail as your domain, whether SPF and DKIM passed, whether they lined up with the domain your prospect actually saw, and what the receiver did with the message. Five fields matter: source IP, count, disposition, and the SPF and DKIM results under policy_evaluated. Read a few weeks of these before you move a domain off p=none, not instead of reading them.
What a DMARC aggregate report actually is
I build the sending infrastructure behind cold email for B2B clients, and the domains that get into trouble are rarely the ones with no DMARC record at all. They're the ones with a record and a rua= reporting address that nobody ever opens. Once that address is live, Gmail, Outlook.com, Yahoo and most other large mailbox providers send a file to it roughly once a day: a list of every server that sent mail claiming to be your domain during that window, whether SPF and DKIM passed, whether either one lined up with your actual From address, and what the receiver chose to do about it. That file is the aggregate report, and it's the only evidence-based way to know whether your domain is ready for a stricter policy, instead of guessing.
I cover setting up the records themselves, SPF, DKIM, and the p=none/quarantine/reject progression, in SPF, DKIM and DMARC explained for cold email. This one picks up where that leaves off: once the record is live and the reports start arriving, here's what's actually in them.
Why reading it matters before you tighten anything
DMARC reports are one piece of the wider deliverability picture, and the one most senders skip because it never shows up as a metric inside a sending platform. p=none is enough to meet Google's, Yahoo's and Microsoft's 2026 bulk sender rules. It asks receivers to do nothing to mail that fails DMARC, just deliver it and send you a report. That's the right starting point and a bad place to stay forever on a domain anyone else might send from, because it stops nothing. The next step, quarantine or reject, only becomes safe once you know that every legitimate sender for your domain is already passing. Guess wrong and you can quarantine or bounce mail from a mailbox or a tool you forgot was sending on your behalf: a billing receipt system, a help desk, a marketing platform someone set up two years ago. The report is how you find out before you flip the switch, not after a client calls asking why their invoice reminder never arrived.
One report isn't enough. A single day can miss a sender that only fires weekly, or catch a one-off problem that fixed itself. Read at least two to three weeks before deciding a domain is clean.
The three parts of the file, in plain language
Every aggregate report, regardless of which provider sent it, follows the same XML shape. It has three sections, and only one of them is where you actually spend your time.
| Section | What it tells you | How often you'll look at it |
|---|---|---|
| report_metadata | Who sent the report and which dates it covers | Once, to confirm it's current |
| policy_published | The DMARC policy the receiver saw published for your domain at the time | Once, to confirm it matches what you actually set |
| record (one or more) | Every source that sent mail as your domain, what happened to each, and why | Every time, this is the part that changes |
If you open the raw file, it'll look dense. In practice you're reading a short list of senders with a pass or fail next to each, repeated once per report.
Report metadata and policy_published: what each field means
These two sections are mostly bookkeeping, worth knowing so you're not confused the first time you see them.
- org_name: who generated the report, usually a provider like Google, Yahoo or Microsoft, not the sender.
- date_range (begin, end): the window the report covers, almost always a single day.
- report_id: a unique ID for that provider's report, useful only if you're troubleshooting with their support.
- policy_published domain, p, sp: the policy the receiver saw for your domain (
p) and subdomains (sp) at the time they checked your DNS. If this doesn't match what you currently have published, your DNS change hasn't propagated to every receiver yet. - adkim, aspf: the alignment mode, relaxed (
r) or strict (s), for DKIM and SPF. Almost every domain runs relaxed, the default.
None of this tells you whether your mail is actually getting through. That's entirely in the next section.
The record block: source IP, count, disposition, alignment
Each record is one sending source during that reporting window. Five fields decide whether it's something to worry about:
| Field | What it means |
|---|---|
| source_ip | The server that actually sent the mail |
| count | How many messages came from that IP in the window |
| disposition | What the receiver did: none, quarantine or reject |
| policy_evaluated > dkim / spf | Whether DKIM and SPF passed and aligned with your From domain, the actual DMARC result |
| identifiers > header_from | The domain in the From address your prospect actually saw |
The field people miss most often: policy_evaluated can show a pass even when the raw SPF or DKIM check in auth_results underneath it shows something messier, because DMARC only needs one of the two to align. Don't read the two sections as contradicting each other. policy_evaluated is the number that matters.
Reading one without touching raw XML
Nobody reads this format by hand for long. The file itself usually arrives gzipped or zipped, and most senders route it straight to a reader instead of an inbox.
| Option | How it works | Best for |
|---|---|---|
| dmarcian or EasyDMARC | You point your rua= address at their service, they turn every report into a dashboard | Teams that want this watched continuously without building anything |
| Postmark's free DMARC monitor | Point rua= at the address Postmark gives you, get a weekly plain-English email summary | A single domain or a handful, no dashboard login needed. Its free tier caps how many sources and IPs it details; check current pricing for more |
| parsedmarc (self-hosted, open source) | Pulls reports from an inbox and writes them to Elasticsearch, OpenSearch or a CSV | Teams already running their own monitoring stack who'd rather not send DNS data to a third party |
| Reading the XML directly | Unzip it and look at the record blocks yourself | A one-off check, or confirming what a dashboard is actually telling you |
For one or two domains, a dashboard tool is the faster path and the weekly email is usually enough to catch something going wrong. The five fields above are what you're looking for either way, so that part doesn't change.
What a healthy report looks like, and three that aren't
Most of what you'll see falls into a small number of shapes:
- Healthy: source_ip matches your sending platform's known ranges, dkim and spf both pass under policy_evaluated, disposition is none. This should be the overwhelming majority of your volume.
- A platform signing as itself, not you: dkim passes but for a domain that isn't yours, spf fails because the envelope sender belongs to the platform. Mail still gets through today under
p=none, but it would fail alignment under a stricter policy. Fix the signing setup, don't just wait. - A sender you forgot about: a source_ip you don't recognize, sending a small but steady count, failing both checks. Often a help desk, a calendar tool, or an old marketing platform still configured to send as your domain. Find it before tightening the policy, or it stops working the day you do.
- Actual spoofing: an unfamiliar source_ip failing both checks with a count that doesn't match any tool you run, especially if it spikes. This is the pattern DMARC exists to catch, and the reason to not stay on
p=noneindefinitely.
The second and third patterns look identical in the report. The only way to tell them apart is knowing your own sending stack well enough to recognize which IPs belong to you.
When the reports actually say it's safe to move
Move from p=none to quarantine once you can say, with reports to back it up, that every legitimate source sending as your domain passes DKIM or SPF aligned, consistently, across more than one reporting window. Not one clean day, several in a row, since a sender that fires weekly or monthly won't show up in a single day's file. For a domain that only sends cold email through one provider, that bar is usually quick to clear. For a company's main domain, where invoices, support tools and old marketing platforms all send too, give it longer and expect to find at least one forgotten sender before you're done.
Once you're on quarantine and still seeing clean reports after another stretch, reject is the final step. At that point you're not protecting your own mail, which already passes either way: you're stopping someone else from sending as you.
Reading reports across more than one sending domain
Cold email setups rarely run on a single domain. Once you're past two or three, reading each report by hand stops being realistic, and this is where a dashboard tool earns its keep: one view across every domain, flagging the ones with a new or failing source instead of making you open each report individually. The underlying read doesn't change, you're still looking for the same five fields, just across more files at once. I keep the domain checks and the free DNS lookups I use day to day on my free tools page, including one that reads a domain's current SPF, DKIM and DMARC setup from public DNS before I ever look at a report.
The domains worth watching the closest are the ones furthest along in warmup, since a domain mid-warmup sending from a new IP range is exactly the kind of source that shows up unfamiliar in a report until you've seen it a few times.
What I actually check for clients
Across the infrastructure behind 2000+ meetings booked for B2B clients, the read is the same three questions every time: does the volume in the report match what I actually sent, does every source I recognize pass aligned, and is there a source I don't recognize at all. If all three come back clean for a few weeks running, I move the policy. If the second one shows a near-miss, a platform signing under its own domain instead of the client's, I fix that first and don't touch the policy until it's resolved. The report is also the fastest way to catch a client's internal tool (a payroll system, a support platform) that was never in my scope and would otherwise break the day the policy tightens.
Key takeaways
- An aggregate report lists every source that sent as your domain, whether SPF and DKIM passed and aligned, and what the receiver did about it.
- Five fields matter: source_ip, count, disposition, and the dkim and spf results under policy_evaluated.
policy_evaluatedis the DMARC result that counts, even when the raw auth_results underneath look messier.- Read several reporting windows, not one, before moving off
p=none, since weekly or monthly senders won't show up in a single day. - A dashboard tool (dmarcian, EasyDMARC, Postmark's free monitor) or a self-hosted parser (parsedmarc) does the same read at scale across more than one domain.
FAQ
What is a DMARC aggregate report?
A daily XML file a mailbox provider sends to the address in your DMARC record's rua= tag, listing every server that sent mail as your domain, whether SPF and DKIM passed and aligned with your From address, and what the receiver did with the message.
How often do DMARC reports arrive?
Roughly once a day per provider that's seen mail from your domain, covering the previous day. A domain sending through several providers (Google, Microsoft, Yahoo and others) gets a separate file from each.
Why does my report show a source IP I don't recognize?
Usually a sender you forgot was configured on your domain: a help desk, a calendar tool, an old marketing platform, or your current sending platform signing under its own domain instead of yours. Confirm which before assuming it's spoofing.
Is it safe to move from p=none to p=reject right away?
No. Move to quarantine first, once reports show every legitimate source passing aligned across several reporting windows, then to reject after another clean stretch. Skipping straight to reject risks blocking a sender you didn't know was there.
Do I need a tool to read DMARC reports, or can I do it by hand?
You can read the raw XML for a one-off check, it's just gzipped or zipped text. For ongoing monitoring across more than a domain or two, a dashboard tool or a self-hosted parser like parsedmarc saves the manual unzip-and-read every day.
