SYSTEMS OPERATIONAL
Domains

DMARC Reports Explained: How to Read Them and Reach p=reject

Getwebup 6 min read

You finally turned on DMARC, and now your dmarc-reports@ inbox is filling up with emails from Google and Microsoft carrying .xml.gz attachments nobody can read. You know DMARC is supposed to tell you if someone's spoofing your domain — but the reports themselves look like machine noise. Here's how to actually read them, and how to use them to move from p=none to p=reject without breaking your own mail.

Symptom: reports arrive, but nobody can make sense of them

If you've had a DMARC record with an rua= address for more than a day, you're probably seeing one of these:

  • A daily flood of emails from noreply-dmarc-support@google.com, dmarc@microsoft.com, and dozens of smaller providers, each with a gzipped XML attachment
  • Reports that open into a wall of <record> blocks with IP addresses and pass/fail codes, but no obvious "you're fine" or "you're being spoofed" summary
  • Uncertainty about whether it's safe to tighten your policy from p=none to p=quarantine or p=reject, because you can't tell if the "fail" rows are attackers or just your own marketing tool

This is normal. DMARC aggregate reports are built for machines first, humans second. You just need to know which five fields actually matter.

Cause: the report format is verbose by design

Every domain that received mail claiming to be from you, and that supports DMARC, sends back one XML report per day (per receiver) summarizing every message it saw. A single report can contain dozens of <record> entries — one per sending IP, not per message — each with its own SPF and DKIM results. That's useful data, but raw XML wasn't meant to be read in a mail client.

The fields that actually matter

XML elementWhat it tells you
source_ipWhich server actually sent the mail. Compare this against your known senders (your host, your CRM, your newsletter tool)
countHow many messages matched this exact result from this IP that day
dispositionWhat the receiver did: none, quarantine, or reject
spf / resultWhether SPF passed for this batch
dkim / resultWhether DKIM passed
header_fromThe domain shown in the visible "From" address — this is what has to line up with SPF/DKIM for DMARC to pass ("alignment")

DMARC doesn't require both SPF and DKIM to pass — it requires at least one to pass and be aligned with the visible From domain. That single rule explains most of the confusing rows you'll see.

Fix: turn the XML into something readable, then triage it

Step 1: Stop reading raw XML by hand

Unzip one report to see the shape of the data once, then stop. For anything beyond a handful of emails a day, use a parser instead of eyeballing attachments:

  • Command line: a short Python script with xml.etree.ElementTree (or the parsedmarc package) turns every attachment in a mailbox into a CSV you can sort and filter
  • Free web tools: services like dmarcian's free checker or EasyDMARC's report analyzer accept a raw report and render it as a table
  • Dedicated inbox: for production domains sending real volume, route rua= to a tool built for this (dmarcian, Postmark, Valimail) instead of a personal mailbox — you'll get trend graphs instead of a daily attachment dump

Step 2: Group by source_ip, not by message

Every day, sort the parsed rows by source_ip and ask one question per IP: "do I recognize this sender?" You'll typically end up with three buckets:

  • Your own mail server (Getwebup/cPanel outbound IP) — should show SPF pass, DKIM pass, aligned
  • Known third parties — your CRM, transactional email API, marketing platform, help desk — check each one individually against what you actually authorized in your SPF include: list
  • Unrecognized IPs — this is what DMARC exists to catch. If the volume is high and disposition shows none because your policy is still p=none, that traffic isn't being blocked yet

Step 3: Don't panic at every "fail" row

Two failure patterns are common and usually harmless:

  • SPF fails, DKIM passes and aligns — almost always mail forwarding. When a recipient forwards your email, the forwarding server becomes the new sending IP, which breaks SPF by design. As long as DKIM still passes and is aligned, DMARC passes overall and nothing is wrong.
  • DKIM fails, SPF passes and aligns — usually a mailing list or gateway that modified the message body or subject line, invalidating the DKIM signature. If SPF is aligned, you're still fine.

What you're actually hunting for is rows where both SPF and DKIM fail, from an IP you don't recognize, with a header_from matching your domain. That's spoofing.

Moving from p=none to p=reject without breaking your own mail

Don't jump straight to enforcement. Ramp it over a few weeks using the pct tag to control what percentage of failing mail actually gets actioned:

StageDMARC recordWhat it does
1. Monitorv=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.comCollects reports, blocks nothing. Run this for 2–3 weeks minimum
2. Partial enforcev=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc-reports@yourdomain.comSends 25% of failing mail to spam instead of the inbox — a safety net if something's still misconfigured
3. Full quarantinev=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc-reports@yourdomain.comAll unaligned mail gets flagged as spam by receivers
4. Rejectv=DMARC1; p=reject; pct=100; rua=mailto:dmarc-reports@yourdomain.comUnaligned mail is refused outright. Only move here once reports show zero legitimate failures for 1–2 weeks straight

Update the record in cPanel under Zone Editor → Manage → _dmarc TXT record. Each stage change takes effect as soon as DNS propagates, usually within an hour, so don't jump two stages in the same day — give each one time to generate fresh reports before tightening further.

Prevention: keep DMARC useful long-term

  • Add a new include: to your SPF record and confirm its DKIM selector before switching on any new email tool — don't wait for the report to tell you it broke
  • Check reports monthly even after reaching p=reject — a new spoofing attempt or a misconfigured integration will show up there first
  • Keep a short list of "known good" sending IPs and SPF includes somewhere your team can see, so triage doesn't start from zero every time
  • If report volume is too high to skim manually, that's the signal to move to a proper aggregator rather than ignoring the emails — an ignored DMARC inbox defeats the point of turning it on

DMARC reports look intimidating on day one, but once you know that alignment — not raw pass/fail — is what actually matters, most rows sort themselves into "expected" or "investigate" within a few minutes a day.

Frequently asked questions

Why am I getting reports from senders I've never heard of?

Those are usually large mailbox providers (Gmail, Outlook, Yahoo) reporting on mail that claimed to be from your domain and landed in their users' inboxes, not senders you know personally. Check the source_ip against your own infrastructure before assuming it's spam or spoofing.

Do I need both SPF and DKIM to pass for DMARC to pass?

No. DMARC passes if at least one of SPF or DKIM passes and is aligned with the visible From domain. Seeing one fail while the other passes and aligns is normal, especially with forwarding (breaks SPF) or mailing lists (breaks DKIM).

How long should I stay on p=none before tightening my policy?

Give it at least 2-3 weeks so you capture a full cycle of your regular senders, including any weekly or monthly newsletters. Don't move to p=reject until reports show zero unexplained failures from your own legitimate mail for at least a week.

Can I get DMARC reports sent to my own inbox instead of a tool?

Yes, rua=mailto:you@yourdomain.com works fine for low volume. Once you're getting more than a handful of reports a day, a parser or aggregator saves real time since you'll otherwise be opening gzip attachments by hand.

What does ruf= do differently from rua=?

rua= gets you daily aggregate summaries (what this guide covers). ruf= requests forensic reports with details of individual failing messages, sent close to real time. Few providers honor ruf= anymore due to privacy concerns, so rua= is where almost all useful data actually shows up.

#dmarc #dmarc-reports #spf #dkim #email-deliverability #dns

Keep reading

Chat with Support