ValidEmailChecker

Free DMARC Report Analyzer

Drop your DMARC reports (.xml or .xml.gz). Get a plain-English summary, per-source breakdown, spoof vs. legit verdict, and fix steps. Everything runs in your browser.

Multi-File + .gzSource BreakdownNo Upload to Server

No DMARC record yet? Build one with the DMARC Generator. Want to check what your current policy says? The DMARC Checker parses it in plain English. This analyzer is for the reports you receive AFTER your record is live.

Drop DMARC reports here, or click to select

.xml or .xml.gz · Multi-file supported · Up to ~100 reports per batch

Everything runs in your browser — files never leave your machine

How it works

1

Drop in your reports

Select one or more DMARC aggregate (RUA) reports — XML or gzipped XML, multi-select supported. Or paste raw XML directly. Everything runs in your browser; nothing is uploaded.

2

Read the summary + insights

See total volume, DMARC pass rate, and a prioritized list of issues with plain-English explanations and concrete fix steps. The biggest problems surface first.

3

Drill into sources

Inspect the per-IP table. Each source is classified (legitimate, forwarder, misconfigured, suspicious) so you know whether to authorize, fix, or block it. Export to CSV or JSON to share.

What a DMARC aggregate report actually contains

Every receiver that supports DMARC — Google, Yahoo, Microsoft, AOL, Mail.ru, Yandex, and dozens of smaller ones — sends a daily XML report to the address in your `rua=mailto:` tag. The format is defined in RFC 7489 Appendix C. It's not designed to be read by humans. Each report covers one day of mail observed from your domain at that single receiver, and looks roughly like this:

<feedback>
  <report_metadata>
    <org_name>google.com</org_name>
    <date_range><begin>1704067200</begin><end>1704153600</end></date_range>
  </report_metadata>
  <policy_published>
    <domain>example.com</domain>
    <p>none</p><pct>100</pct>
  </policy_published>
  <record>
    <row>
      <source_ip>198.51.100.10</source_ip>
      <count>42</count>
      <policy_evaluated><disposition>none</disposition><dkim>pass</dkim><spf>pass</spf></policy_evaluated>
    </row>
    ...
  </record>
</feedback>

The interesting part is the `<record>` blocks. Each one represents N messages from one source IP to that receiver, with the authentication result. Roll those across multiple reports and multiple receivers and you get a real picture of who's sending mail using your domain — including senders you don't recognize.

Why most reports come as .xml.gz

Reporters gzip the XML before sending to keep the email payload small. A typical Google daily report is 20–50 KB compressed and 200–500 KB uncompressed. You'll see filenames like `google.com!example.com!1704067200!1704153600.xml.gz`.

This tool unzips `.gz` natively in your browser — no need to decompress first. Drop the file in straight from your email attachment download. (Microsoft sometimes sends `.zip` archives containing the XML — unzip those once and upload the XML inside.)

Drop multiple files at once

Reports cover one day at one receiver. To see real patterns you want at least a week from each receiver — that's 30–60 files. Select them all in the file picker and we aggregate the whole batch in one shot.

The four buckets we sort each sending source into

Looking at a per-IP table of pass/fail rates isn't actionable. We classify each source IP into one of these buckets so you know what to do with it:

BucketPatternWhat to do
LegitimateHigh DMARC pass rate, auth domains match your header-fromNothing — this sender is configured correctly.
ForwarderSPF fails but DKIM survives (mailing lists, .edu aliases)Nothing — DKIM-only alignment still passes DMARC. ARC sealing helps if you're behind p=reject.
MisconfiguredHigh volume, mostly failing, but auth domains look familiar (your ESP, your domain)Fix the SPF/DKIM config. Usually a missing SPF include or DKIM selector not published.
SuspiciousNo DKIM aligned to your domain, no recognized sender, low pass rateInvestigate. Could be a forgotten internal service or a spoofing attempt.

The classifier looks at DKIM signing domains, SPF return-path domains, and a list of around 25 known ESPs (SendGrid, Mailchimp, SES, Mailgun, Postmark, etc.) to decide which bucket fits. It's a heuristic — we show the raw numbers next to every verdict so you can second-guess us.

How to read the failure summary

When a record shows DKIM `fail` or SPF `fail`, the cause is almost always one of these:

  • SPF not authorized — the sending IP isn't covered by your SPF record's mechanisms. Use the SPF Syntax Validator to walk through every `include:` chain and find what's missing.
  • SPF aligned but soft-failing — your record uses `~all` or `?all`. Receivers report 'softfail' which DMARC treats as a fail for alignment purposes.
  • DKIM signature missing — the sender isn't signing at all, or is signing with the provider's domain instead of yours. Re-enable DKIM signing in your ESP and point it at your domain.
  • DKIM signature broken — the signature was applied but failed validation. Usually a footer-injection rewrite (some mailing platforms add unsubscribe text after signing) or a body-canonicalization mismatch.
  • DKIM key not found — selector is signing but the public key isn't published at `<selector>._domainkey.<your-domain>`. Re-publish the TXT record your ESP gave you.
  • Subdomain alignment mismatch — your `From:` is `marketing.example.com` but you're signing with `example.com`. Use `adkim=r` (relaxed) instead of `adkim=s` (strict) in your DMARC record.

When to move from p=none → p=quarantine → p=reject

A DMARC rollout is a careful ratchet. Push to enforcement too soon and you bounce legitimate mail. Stay at observation too long and you stay vulnerable to spoofing. The right cadence:

StageRecordWait forMove on when
1. Observe`p=none; rua=mailto:dmarc@yourdomain.com`7–14 days of reportsYou see all expected senders + know which IPs are which
2. Soft enforce`p=quarantine; pct=25`14 days<1% legitimate mail in spam, no rise in support tickets
3. Ramp up`p=quarantine; pct=100`14 daysSame — no spam complaints from your audience
4. Reject 25%`p=reject; pct=25`14 daysNo bounce reports from senders you care about
5. Full reject`p=reject; pct=100`OngoingYou're done. Keep watching reports for new IPs.

If you don't have a DMARC record published yet, build one first with our DMARC Record Generator. If you have one but you're not sure what it says, the DMARC Record Checker parses it in plain English.

What this analyzer doesn't do (and what to use instead)

Three deliberate omissions worth knowing about:

  • No RUF (forensic) report parsing yet. RUF reports are per-message failure samples with redacted headers. Most receivers stopped sending them years ago for privacy reasons. If you need them, paid services like Dmarcian and EasyDMARC still aggregate the trickle that remains.
  • No reverse-DNS for source IPs. A PTR lookup would tell you that `198.51.100.10` is `mail.acme.io` — useful context. We skip it because doing it client-side without a CORS proxy is impossible, and the obvious next step (a server function) drags this tool out of the 'no backend' category. Look up unfamiliar IPs in our IP Lookup tool separately.
  • No historical persistence. Each upload analyzes the files in front of it. There's no 'last 30 days' dashboard because we don't store anything — everything runs in your browser tab. Save the JSON export if you want a record.

Privacy: nothing leaves your browser

DMARC reports contain real source IPs and per-message counts. Uploading them to a third-party service means handing over a list of every IP that ever sent mail using your domain — that's a meaningful security disclosure. This tool runs entirely in your browser tab. XML parsing uses native DOMParser. Gzip decoding uses native DecompressionStream. There is no network request to our servers when you analyze a report.

When you click Export → CSV or Export → JSON, the file is generated in your browser and downloaded to your machine via a blob URL. We never see the contents.

Frequently Asked Questions

Questions about uploading DMARC reports, reading the per-source breakdown, the spoof-vs-legit verdict, and how this differs from paid SaaS aggregators.

Drop the .gz file in as-is. We decompress it natively in the browser using DecompressionStream — no separate unzip step needed. Works in Chrome, Edge, Firefox, and Safari (all evergreen versions since 2022). If your browser is older we surface a friendly message asking you to unzip first.

For a useful picture, aim for 7–14 days from each receiver — that's usually 30–60 files. One report = one day from one receiver. The aggregator handles however many you drop in one shot.

Microsoft sometimes wraps the XML in a .zip archive instead of gzipping it directly. We don't unpack .zip in the browser yet (too much bundle weight for an edge case). Unzip it once and upload the .xml file inside.

A forwarder is a mail relay — usually a mailing list service, a .edu alias, or a corporate forwarding rule — that takes mail from you and re-sends it to the final recipient. Forwarding breaks SPF (the relay's IP isn't in your SPF record) but DKIM signatures survive intact if nothing modifies the message. DMARC passes on DKIM alignment alone, so most forwarded mail still delivers fine.

Not yet. 95% means 1 in 20 messages is failing — that includes legitimate mail you might bounce. Stay at p=quarantine pct=100 for 2 weeks watching for new IPs. Then move to p=reject pct=25, watch another 2 weeks, then pct=100. Rushing to reject and immediately seeing a chunk of newsletter mail bounce is the most common DMARC rollout mistake.

Maybe, but cross-reference internal services first. The most common culprit is a forgotten contractor account, an old marketing tool, a CRM plugin, or a recently-added support helpdesk that nobody added to SPF/DKIM. Genuine spoofers usually send small bursts and stop when DMARC starts blocking them. A high-volume unknown sender is more likely a misconfigured legitimate service.

Reports only come from receivers who actually got mail from your domain that day. If you only send to Gmail-using contacts, Google will be your only reporter. To get broader coverage, give it 7–14 days of normal sending — eventually you'll see reports from Yahoo, Microsoft, AOL, and others.

Export the CSV or JSON — both contain everything shown on screen. Email or Slack it. Since the analyzer runs entirely in-browser, there's no shareable link to send.

Those are paid SaaS platforms — you point your `rua=` tag at their address and they aggregate reports for you over time, with dashboards and alerts. This tool is a one-off analyzer: drop a batch of reports, get an answer. Good for first-time setup, occasional audits, or sanity-checking what a paid platform is showing you. It does NOT receive your reports for you.

No — it means the receiver saw no mail from your domain that day. Empty reports are normal during quiet days or right after publishing a brand-new DMARC record (before any mail flows). It's only a concern if every report is empty over a week of active sending.

Still have questions?

Contact our support team →

DMARC clean? Make sure your list is too.

Authentication keeps spoofers out. Verification keeps bounces from wrecking your sender reputation. 200 free credits, no card on signup.