Skip to content
dmarcemail-authenticationguidetroubleshootingemail-deliverability

How to Read DMARC Reports and Roll Out Safely

DMARC aggregate reports arrive as unreadable XML. Here's how to read them, tell a legitimate sender from a spoofer, and move from p=none to p=reject without blocking your own mail.

Udhayakumar M

6 min read

How to Read DMARC Reports and Roll Out Safely
On this page

Your first DMARC aggregate report lands in your inbox as a .xml.gz attachment with a filename like google.com!yourdomain.com!1759708800!1759795200.xml.gz. You open it expecting answers and get a wall of nested tags instead: source_ip, policy_evaluated, identifiers, none of it labeled in a way that tells you what to actually do.

That gap, a record full of real data you can’t act on, is why most domains sit at p=none indefinitely instead of advancing. This post covers how to actually read the XML, how to tell a legitimate sending source from a spoofer, and the specific rollout path from p=none to p=reject that doesn’t block your own mail along the way.

The two types of DMARC reports

Aggregate reports (rua) are daily summaries from each participating mailbox provider: which IPs sent mail claiming to be from your domain, how many messages, and whether each one passed or failed. These are the reports that matter for rollout decisions. They contain no message content, only authentication results and volume.

Forensic reports (ruf) cover individual failed messages in more detail. Most major providers, including Gmail, don’t send them at all, for recipient privacy reasons. Plan your rollout entirely around aggregate reports; treat forensic reports as a bonus if a provider sends them, not something to wait on.

Reading the raw XML, field by field

A single record inside an aggregate report looks like this:

<record>
  <row>
    <source_ip>198.51.100.24</source_ip>
    <count>1482</count>
    <policy_evaluated>
      <disposition>none</disposition>
      <dkim>pass</dkim>
      <spf>fail</spf>
    </policy_evaluated>
  </row>
  <identifiers>
    <header_from>yourstore.com</header_from>
  </identifiers>
  <auth_results>
    <dkim>
      <domain>klaviyomail.com</domain>
      <result>pass</result>
    </dkim>
    <spf>
      <domain>klaviyomail.com</domain>
      <result>pass</result>
    </spf>
  </auth_results>
</record>

Here’s what each piece actually tells you:

  • source_ip: the server that sent the mail. Cross-reference this against your known sending tools, not just your ESP; your helpdesk, review app, and invoicing tool all have their own IPs.
  • count: how many messages came from that IP during the report window. A source_ip you don’t recognize sending 1 message is noise. One sending 10,000 is worth investigating immediately.
  • policy_evaluated → disposition: what actually happened to the mail (none, quarantine, or reject), based on your published policy at the time.
  • policy_evaluated → dkim / spf: whether each check passed, at the raw protocol level, before alignment is considered.
  • identifiers → header_from: the domain the recipient saw, the one DMARC alignment is measured against.
  • auth_results → dkim / spf → domain: the domain that actually signed (DKIM) or was authorized (SPF). Compare this to header_from. If they don’t match, that’s an alignment failure, even when policy_evaluated shows a protocol-level pass.

That last comparison is the one raw XML makes hardest to see at a glance, and it’s the one that matters most. In the example above, DKIM and SPF both pass at the protocol level, but the record only tells you they’re aligned if auth_results’s domain matches identifiers’s header_from. Our common DMARC errors guide covers this exact alignment gap if you’re seeing it in your own reports.

Turning raw records into a decision

Once you’ve read enough individual records, the pattern that matters is which sources are sending, not each individual record. Group by source_ip or by the sending domain in auth_results, and you get something like this:

Source Emails SPF aligned DKIM aligned Verdict
Klaviyo 1,482 No Yes Legitimate, passing on DKIM
Google Workspace 640 Yes Yes Legitimate
Unknown IP (203.0.113.25) 210 No Yes Likely forwarding
Unknown IP (192.0.2.77) 320 No No Investigate

A DMARC report analyzer does this grouping automatically and usually names the service behind an IP range (Klaviyo, SendGrid, Google Workspace) instead of leaving you to look it up. Worth using once you have more than one or two sending sources, since reading raw XML by hand stops scaling fast.

Get your reports parsed and grouped automatically

Sending sources named by service, alignment failures tracked, alerts when your pass rate drops.

Telling a legitimate sender from a spoofer

Three patterns cover almost everything you’ll see once you’re reading reports regularly.

Known service, everything aligned. Your ESP, Google Workspace, your transactional provider. Nothing to do.

DKIM aligned, SPF failing, from an IP you don’t recognize. Usually forwarding, not spoofing. A recipient auto-forwards your mail to another address, which breaks SPF because the forwarding server isn’t in your SPF record, while the DKIM signature survives intact because the message content wasn’t altered. This is exactly why DKIM alignment matters more than SPF alignment when you’re deciding how worried to be about a given record.

Both failing, unfamiliar IPs, meaningful volume. Worth investigating, but check internally before assuming an attack. In practice, across client audits, it’s a marketing or helpdesk tool someone in the business signed up for without telling anyone about as often as it’s an actual spoofing attempt. A quick internal Slack message asking “did anyone add a new tool that sends email” resolves more of these than threat-hunting does.

The rollout path: p=none to p=reject

A Realistic Rollout Timeline

2-4 wksminimum at p=none before moving
4-8 wkstypical first report to p=reject, ecommerce
98%+legitimate pass rate to target before enforcing
1-2 wksrecommended time at p=quarantine before p=reject

Stage 1: p=none

Publish v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com and wait. This delivers mail exactly as before, nothing is blocked, but it starts the reports flowing. Stay here for at least 2 to 4 weeks, and long enough to cover a full sending cycle for your business, not just a calendar minimum. Monthly or quarterly sends, invoicing, seasonal campaigns, a review-request flow triggered on a delay, won’t show up in two weeks of reports, and each one will fail the moment you enforce if you haven’t seen it pass first.

Target comfortably above 98% of legitimate volume passing and aligned before you consider moving on. If a known source is below that, fix its authentication and wait for the next report to confirm before advancing.

Stage 2: p=quarantine

Move to p=quarantine once your reports are clean. This is the safety net: failing mail goes to spam instead of being blocked outright, so a source your audit missed is recoverable, not lost. Watch for one to two weeks. If legitimate mail starts landing in spam during this window, that’s almost always a source that wasn’t passing alignment before enforcement started catching it, not a new problem. Check your aggregate reports from the days right after the policy change for any known source showing a fail or a non-aligned pass, fix that source’s authentication, and confirm it clears in the next report.

Stage 3: p=reject

Move to p=reject only once p=quarantine shows nothing legitimate failing. At this point, failing mail is blocked outright rather than delivered to spam, so there’s no more safety net if something was missed. This is also the point where BIMI becomes available if a logo in the inbox matters to you.

Under DMARCbis, if you want a softer intermediate step than the old percentage ramp, use t=y as a testing flag rather than a partial pct= value, which RFC 9989 deprecated.

The mistake that breaks this rollout

Jumping straight from p=none to p=reject, skipping p=quarantine entirely. It feels faster, but it removes the one stage where a missed source costs you spam placement instead of a bounced, unrecoverable send. Two steps, not one, is what makes this rollout safe rather than just fast.

Check where your domain’s policy actually stands

Free, no signup. Confirms your current policy and flags sources still failing before you advance it.

The bottom line

  • Read auth_results against identifiers, not just policy_evaluated. That comparison is where alignment, the thing that actually determines pass or fail, actually lives in the XML.
  • Group records by source before reading them individually. The decision you need to make is about a sending source, not about any single record.
  • DKIM-aligned, SPF-failing from an unfamiliar IP is usually forwarding, not an attack. Check both-failing sources internally before assuming the worst.
  • Rollout in two steps: p=quarantine before p=reject. Skipping the middle stage removes the only safety net in the process.
  • A full sending cycle, not two calendar weeks, is what “long enough at p=none” actually means. Quarterly and seasonal sends need to show up in reports before you enforce.

Frequently Asked Questions

How do I read a DMARC aggregate report?
Aggregate reports arrive as XML attachments, usually daily, from each mailbox provider that received mail claiming to be from your domain. Each record shows a source_ip, a count of messages from that IP, whether SPF and DKIM passed and aligned, and the policy that was applied. Read it by sorting records into known senders (your ESP, Google Workspace, transactional tools) and unknown ones, then checking whether each known sender is actually aligning, not just sending.
What is the difference between DMARC aggregate and forensic reports?
Aggregate reports (rua) are daily summaries: which IPs sent mail as your domain, how many messages, and whether they passed. They contain no message content. Forensic reports (ruf) include details on individual failed messages, but most major providers, including Gmail, don't send them for privacy reasons. Plan your rollout around aggregate reports; treat forensic reports as a bonus if you get them at all.
How long should I stay at DMARC p=none before moving to quarantine?
At least 2 to 4 weeks, and long enough to cover a full sending cycle for your business, not just a calendar minimum. If you have monthly or quarterly sends, like invoicing, seasonal campaigns, or a review-request flow, those need to show up in your reports before you enforce, or you'll block them the moment you move to quarantine. For a typical ecommerce brand with a normal tool stack, four to eight weeks from first report to p=reject is realistic.
Why are my legitimate emails going to spam after I set DMARC to quarantine?
Almost always because a legitimate sending source wasn't passing alignment when you moved off p=none, and it only showed up in your reports after enforcement started catching it. Check your aggregate reports from the days right after the policy change for any known source showing a fail or non-aligned pass. Fix that source's authentication, confirm it passes in the next report, and the quarantine effect stops once the new DNS and reports propagate.
How do I move from p=none to p=reject without breaking my email?
Move in two steps, not one. First, confirm every legitimate source passes alignment at p=none for a full sending cycle, not just two clean weeks. Second, move to p=quarantine and watch for one to two weeks: quarantine still delivers mail, just to spam, so a source you missed is recoverable rather than lost. Only move to p=reject once quarantine shows nothing legitimate failing. Jumping straight from p=none to p=reject skips the safety net that catches what your initial audit missed.
How do I tell a legitimate sender from a spoofer in my DMARC reports?
Three patterns cover most cases. A known service (your ESP, Google Workspace, a transactional provider) with both SPF and DKIM aligned is legitimate, nothing to do. DKIM passing while SPF fails from an unfamiliar IP is usually mail forwarding, not spoofing, since forwarding breaks SPF but typically leaves the DKIM signature intact. Both SPF and DKIM failing from unfamiliar IPs at meaningful volume is worth investigating, but check internally first; in practice it's a marketing tool someone signed up for without telling you about as often as it's an actual spoofing attempt.
Udhayakumar M
Udhayakumar M·Content Marketer

With 8+ years writing for 80+ SaaS products, Udhay knows how to make complex ideas land. At InboxEagle, he turns email deliverability data into plain-English strategy — helping eCommerce brands understand why emails end up where they do, and what to do about it.

LinkedIn
Share this article:Share on XShare on LinkedIn
Explore with AI

Open this content in your AI assistant for deeper analysis, or copy it as Markdown to paste anywhere.

ChatGPTClaudePerplexity

Related Articles

One deliverability insight, every Friday.

Trusted by 2,000+ email senders. Free, always.

Free Checklist

The exact checklist used by 2,000+ email senders to diagnose and fix inbox placement issues — free.

  • Authentication setup (SPF, DKIM, DMARC)
  • Sender reputation signals to monitor
  • List hygiene benchmarks
  • Content & engagement red flags

No spam. Unsubscribe any time.