FREE · NO ACCOUNT REQUIRED

Free DMARC checker — grade, AI diagnosis, and copy-paste fixes for any domain.

DMARC Checker pulls the TXT record at `_dmarc.<domain>`, parses every tag (`p`, `sp`, `pct`, `rua`, `ruf`, `adkim`, `aspf`, `fo`, `rf`, `ri`), validates syntax against RFC 7489, and returns an A–F letter grade computed from the *effective* enforcement (policy × pct/100 — not just the tag value). Includes cross-domain `_report._dmarc` authorization check, bulk-sender compliance chips for Google/Yahoo 2024 and Microsoft 2025, BIMI eligibility, a six-step rollout stepper synced to your live state, and a plain-English AI diagnosis with copy-paste TXT fix snippets. Tells you not just whether DMARC is present, but exactly what to publish next.

01 · OVERVIEW

What the tool outputs

Five tabs, seven independent classes of output per DMARC check. The A–F grade + effective-enforcement math and the cross-domain reporter authorization check are the differentiators most other tools don't do.

A–F grade + enforcement score (Summary tab)

Effective enforcement = policyScore × (pct/100). `p=reject; pct=100` scores 2.0 (grade A). `p=reject; pct=10` scores only 0.2 (grade C — a partial rollout most tools miss). The badge is a colour-coded ring around the letter — fills proportionally to the score.

Plain-English AI diagnosis (AI-powered)

Every check gets a 2–3 sentence summary in plain English, severity-tagged findings (critical / warning / info), and 3–5 imperative bullet recommendations. Not generic DMARC theory — tied specifically to what your record actually says right now.

Copy-paste fix snippets (One-click)

For each critical or warning finding, the AI emits a copy-pasteable TXT record showing the corrected DMARC record, plus a `dig` command to verify after you publish. Terminal-styled cards with one-tap copy. Skip the trial-and-error editing.

Cross-domain report authorization (RFC 7489 § 7.1)

When your `rua=` points to a mailbox on a different domain, RFC requires the reporter to publish `<yourdomain>._report._dmarc.<reporter>` — otherwise reports are silently dropped. We check this for every external URI and surface unauthorized reporters as a warning.

Bulk-sender compliance chips (Google · Yahoo · MS · BIMI)

Instant green/grey pills for Google/Yahoo 2024 (Feb 2024 bulk-sender rules), Microsoft 2025 (aligned May 2025), and BIMI eligibility. `p=none` clears the bulk-sender floor; only `p=quarantine`/`reject` at `pct=100` unlocks BIMI.

Six-step rollout stepper (Live-state sync)

Interactive ladder from `p=none` to `p=reject; pct=100`. The step matching your current policy + pct + rua state gets a 'You are here' pill, and the next-step TXT snippet renders inline — ready to publish.

Severity-tagged validation tests (Tests tab)

Eleven RFC-based checks grouped by high/medium/low severity — including single-record enforcement (RFC 7489 forbids multiples), pct rollout, external reporter authorization, alignment strictness, and subdomain policy. Pass rate + gradient progress bar at the top.

Every tag decoded (Record & Tags tab)

Full tag table with three columns: current value, plain-English meaning, and RFC default. Custom values highlighted in blue, defaults muted grey — instantly spot what's non-standard. Reporting destinations rendered with the cross-domain auth badge inline.

02 · WHY THIS MATTERS

Why DMARC is the policy layer that ties everything together

SPF and DKIM each answer one narrow question. DMARC is what tells receivers what to do with the answer — and what to report back to you. Without DMARC, you have authentication but no enforcement and no visibility. Five reasons it matters in 2026:

  • Without DMARC, attackers can spoof your domain at zero cost. SPF lists allowed IPs; DKIM signs content. Neither says what receivers should DO when both fail. Without a DMARC policy, receivers fall back to per-mailbox heuristics — Gmail, Outlook, and Yahoo each make their own decision, and the decision usually favors delivering the spoofed mail to inbox or junk rather than rejecting it.
  • `p=none` is monitor-mode, not protection. Most domains we audit publish DMARC at `p=none`. That's a useful starting point — it gets you aggregate reports without rejecting any mail — but it provides zero spoofing protection. Real protection requires moving to `p=quarantine` or `p=reject`. Our grade drops it to D (monitor only) so the gap is loud.
  • Major providers now require DMARC for bulk senders. Google and Yahoo's 2024 bulk-sender requirements mandate a published DMARC policy for any sender over 5,000 messages/day. Microsoft's 2025 update extended similar requirements. A missing or `p=none` DMARC at scale now translates directly to deliverability degradation. Our compliance chips light up green the moment you clear each threshold.
  • Aggregate reports are how you find shadow senders. Without `rua=`, you have no visibility into who's sending mail as your domain. With it, daily XML reports from Gmail, Microsoft, Yahoo, and ~30 other receivers show you every sending IP that hit them — including the third-party tools your marketing team set up six months ago and never told you about.
  • Misconfiguration is silent. A typo in `rua=`, a malformed `pct=`, missing cross-domain authorization for an outsourced DMARC service — none of these fail loudly. Reports just don't arrive, or the policy reads as something subtly different from what you intended. Our tool surfaces the `_report._dmarc` authorization miss explicitly — most checkers don't.
03 · HOW IT WORKS

TXT lookup → tag parse → validation → grade → AI diagnosis

A DMARC check is a TXT query, a structural parse, a few outbound checks, a grade computation, and an AI review. We follow the same algorithm a receiving mail server would when deciding whether and how to apply policy to inbound mail — and then add the layer that turns raw data into action.

  • Stage 1 — Fetch the DMARC record Query TXT at `_dmarc.<domain>`. Filter for records starting with `v=DMARC1`. Detect multiple DMARC records — that's an instant disqualification at any receiver, and we surface it as a high-severity failure instead of hard-throwing.
  • Stage 2 — Parse every tag DMARC records are semicolon-separated `tag=value` pairs. Required: `v=DMARC1` and `p=`. Optional: `sp`, `pct`, `rua`, `ruf`, `adkim`, `aspf`, `fo`, `rf`, `ri`. Every tag is parsed against its valid-values list; `pct` correctly typed as integer (a bug we found in most reference implementations).
  • Stage 3 — Score the effective enforcement `p=none` → 0, `p=quarantine` → 1, `p=reject` → 2. Multiplied by `pct/100`. `p=reject; pct=10` scores 0.2 — not 2.0. That's the number that actually matters, and the number we grade against.
  • Stage 4 — Validate reporting URIs Parse `rua=` and `ruf=` URIs. Validate `mailto:` syntax. When the reporter domain differs from the published domain, query `<yourdomain>._report._dmarc.<reporter>` — if no `v=DMARC1` TXT record is found there, mark the reporter as unauthorized. Silently-dropped reports are one of the most common invisible failures; this check catches them.
  • Stage 5 — Read alignment modes Default `adkim=r` and `aspf=r` (relaxed, organizational-domain match). Strict (`s`) is flagged as a medium-severity risk — it breaks any sender using a sending subdomain. Most setups should be relaxed.
  • Stage 6 — Compliance derivation Google/Yahoo 2024 + Microsoft 2025 compliance chips light up when a published policy exists (`p ∈ {none, quarantine, reject}`). BIMI eligibility requires `p=quarantine`/`reject` at `pct=100` — the same check the BIMI receivers do.
  • Stage 7 — AI diagnosis + fix snippets Feed the parsed record, cross-domain results, grade, and tests to the analyzer. Returns a 2–3 sentence plain-English summary, 3–5 imperative recommendations, severity-tagged findings, and up to 4 copy-pasteable TXT fix snippets (with a `dig` verify command). Skips generic DMARC theory — findings are tied to your exact record.
04 · GRADING

How the A–F grade is computed

Grade is a function of policy strength, pct rollout, and whether aggregate reporting is configured. Same signals a receiver uses to decide enforcement — packaged as a single letter you can put on a status board.

  • A — Full enforcement (score 2.0) `p=reject` AND `pct=100` AND `rua=` set. Failing mail rejected outright; aggregate reports flow; BIMI eligible.
  • B — Strong (score 1.0) `p=quarantine` AND `pct=100` AND `rua=` set. Failing mail routed to junk; aggregate reports flow. Below-inbox protection but no reject.
  • C — Partial rollout (score 0.2–1.9) `p=reject` or `p=quarantine` BUT `pct<100`. The classic `pct=10` trap — reads as reject, only enforces on a slice. Downgraded to C so nobody misses it.
  • D — Monitor-only (score 0.0) `p=none` WITH `rua=`. You get reports but no protection. Useful bootstrap state; grade signals that this is a stop, not a destination.
  • F — Unprotected No DMARC record, invalid syntax, multiple records, or `p=none` without `rua=`. No enforcement, no visibility. Grade lets you flag this on any dashboard.
05 · TERMINOLOGY

SPF vs DKIM vs DMARC — what each one actually does

Three terms, three layers. DMARC sits on top of SPF and DKIM and makes the enforcement decision. The shortest framing: SPF authorizes IPs, DKIM signs messages, DMARC sets policy.

  • SPF — Sender Policy Framework Lists which IPs can send mail for your domain. Lives at the apex as a TXT record. IP-based; breaks under forwarding. See the SPF Checker for full chain expansion and 10-lookup-limit analysis.
  • DKIM — DomainKeys Identified Mail Cryptographically signs outgoing messages with a private key; receivers verify against the public key in DNS. Content-based; survives forwarding. See the DKIM Checker for per-selector lookup and key-strength scoring.
  • DMARC — Domain-based Message Authentication, Reporting, and Conformance Tells receivers what to do when SPF or DKIM fails. Lives at `_dmarc.<domain>`. Adds reporting so you find out who's authenticating as you. Policy-based — coordinates the underlying mechanisms. This is the tool you're looking at.
  • Alignment is the DMARC-specific concept DMARC passes only when SPF or DKIM aligns — meaning the authenticated domain matches the `From:` domain. SPF can pass on a different envelope sender, DKIM can pass with a different signing domain — but DMARC fails unless one of them aligns with the visible From. This is what makes DMARC harder to set up than either underlying mechanism.
  • What this tool covers DMARC only. For SPF, see the SPF Checker. For DKIM, see the DKIM Checker. For a combined health view across all three plus deliverability gradings, see the Email Authentication tool.
06 · TAGS

Every DMARC tag, explained

A DMARC record is a sequence of `tag=value` pairs separated by semicolons. Only `v=DMARC1` and `p=` are required; everything else is optional with sensible defaults. The Record & Tags tab shows current-vs-default side by side — non-default values in blue, defaults muted.

  • v=DMARC1 — Version (required, first) Identifies the record as DMARC version 1. Must be the literal string `v=DMARC1` and the first tag. Without it, the TXT record is just text, not DMARC.
  • p= — Main policy (required) Tells receivers what to do when a message fails DMARC. `none` (monitor only — useful while bootstrapping, no protection), `quarantine` (mark as suspicious, typically junk), `reject` (block entirely). Production goal: `p=reject`.
  • sp= — Subdomain policy (optional) Overrides `p=` for subdomains. If absent, subdomains inherit `p=`. Use case: enforce `p=reject` on the main domain but `sp=quarantine` on subdomains during transition.
  • pct= — Rollout percentage (optional, default 100) Apply the policy to only this percentage of mail; the remainder gets the next-weakest treatment. `p=reject; pct=10` means 10% of failing mail is rejected, 90% is quarantined. The classic 'stuck rollout' trap — our grade drops from A to C the moment pct<100.
  • rua= — Aggregate report URI (optional, strongly recommended) Where to send daily aggregate XML reports. Almost always a `mailto:` URI. Without `rua`, you publish a policy and have no visibility. External reporter mailboxes need a cross-domain `_report._dmarc` authorization record — we check this automatically.
  • ruf= — Forensic report URI (optional, rarely supported) Per-failure reports with message details. Few receivers actually send forensic reports anymore due to privacy concerns. Usually safe to omit.
  • adkim= — DKIM alignment mode (optional, default `r`) `r` (relaxed) — DKIM signing domain can be any subdomain of the From domain. `s` (strict) — must exactly match. Strict is flagged as medium-severity risk in our tests.
  • aspf= — SPF alignment mode (optional, default `r`) Same as `adkim`, but for SPF. Strict aspf breaks any sender using a sending subdomain.
  • fo= — Failure-reporting options (optional, default `0`) When to send forensic reports. `0` — only when both SPF and DKIM fail. `1` — when either fails. `d` — DKIM fails. `s` — SPF fails. Combinable (`fo=d:s`).
  • rf= and ri= — Report format and interval (optional) `rf=afrf` is the only widely-supported value. `ri=86400` is the default aggregate-report interval (24 hours).
07 · ROLLOUT

Going from p=none to p=reject without breaking mail

Moving from `p=none` to `p=reject` is the entire point of DMARC — and the single most common place teams get stuck. The Rollout tab renders these six steps as an interactive ladder that highlights your current position and shows the next TXT record to publish. Copy of the six steps below matches the tool exactly.

  • Step 1 — Publish `p=none` with `rua=` Goal: gather data. Set `p=none; rua=mailto:[email protected]; pct=100`. Wait at least 2 weeks. Aggregate reports arrive daily from Gmail, Microsoft, Yahoo, and dozens of others. Each report lists every sending IP that authenticated as your domain.
  • Step 2 — Inventory every legitimate sender From the aggregate reports, identify every sender. For each, verify SPF authorizes the sending IP and DKIM is set up with a strong key. Use the SPF Checker and DKIM Checker on each.
  • Step 3 — Fix the failures Reports will show senders failing SPF or DKIM. For each: either add them to SPF, add their DKIM selector, or stop using them. Don't move to enforcement until every legitimate sender passes either SPF or DKIM with alignment.
  • Step 4 — Move to `p=quarantine; pct=10` Enforce on a small slice. Monitor reports daily for the first week. If aggregate counts show legitimate senders being quarantined, roll back, fix, retry. If not, ramp pct.
  • Step 5 — Ramp pct toward 100 pct=10 → pct=25 → pct=50 → pct=100. Spend at least a week at each step. Receiving infrastructure caches DMARC policy for hours; changes take a day or two to fully propagate.
  • Step 6 — Move to `p=reject; pct=100` Maximum enforcement. Spoofing attempts get rejected outright. Continue monitoring aggregate reports forever — new senders get onboarded, services migrate, IPs change. DMARC at `p=reject` is not 'set and forget'.
08 · API

Use this programmatically

Every field — parsed record, policy scoring, cross-domain authorization, compliance flags, tests, AI diagnosis, fix snippets — is available as JSON. Useful for DMARC-rollout monitoring, vendor onboarding, M&A diligence, and continuous policy enforcement.

cURL
curl 'https://api.domainscan.in/v1/domain/dmarc?domain=microsoft.com&tests=true'
JavaScript (fetch)
const res = await fetch(
  'https://api.domainscan.in/v1/domain/dmarc?domain=microsoft.com&tests=true'
);
const {data} = await res.json();

console.log(data.dmarc);                    // raw DMARC TXT
console.log(data.score.grade);              // 'A' | 'B' | 'C' | 'D' | 'F'
console.log(data.score.effectiveEnforcement); // 0.0 – 2.0
console.log(data.compliance.bimiEligible);  // boolean
console.log(data.compliance.googleYahoo2024); // boolean

// Cross-domain reporter authorization
data.reporting.rua.forEach(r => {
  if (!r.authorized) {
    console.warn(`Unauthorized reporter: ${r.uri} (${r.reason})`);
  }
});

// Copy-paste fixes (AI-generated)
(data.AiAnalysis?.fixes || []).forEach(fix => {
  console.log(`Fix: ${fix.issue}`);
  console.log(fix.snippet);
});

// Failing tests grouped by severity
const failing = (data.tests || []).filter(t => !t.passed);
failing.forEach(t => console.warn(`[${t.severity}] ${t.test} — ${t.result}`));
Response schema (abridged)
{
  "found":       true,
  "domain":      "microsoft.com",
  "source":      "domain",
  "recordCount": 1,
  "dmarc":       "v=DMARC1; p=reject; pct=100; rua=mailto:...; adkim=r; aspf=r",

  "parsed": {
    "parsed": { "v": "DMARC1", "p": "reject", "pct": 100, "rua": ["..."], "adkim": "r", "aspf": "r" },
    "descriptions": { "p": "Reject failing mail", "pct": "100% rollout", "...": "..." }
  },

  "score": {
    "grade":                "A",
    "effectiveEnforcement": 2.0,
    "policyStrength":       "reject",
    "pct":                  100,
    "protectionState":      "enforcing"
  },

  "reporting": {
    "rua": [
      { "uri": "[email protected]", "domain": "microsoft.com", "authorized": true, "reason": "same_domain" }
    ],
    "ruf": []
  },

  "compliance": {
    "googleYahoo2024": true,
    "microsoft2025":   true,
    "bimiEligible":    true,
    "hasRua":          true
  },

  "tests": [
    { "test": "DMARC Record Published", "result": "...", "passed": true,  "severity": "high" },
    { "test": "Single DMARC Record",    "result": "...", "passed": true,  "severity": "high" },
    { "test": "Policy Strength",        "result": "...", "passed": true,  "severity": "med"  },
    { "test": "Percent Rollout",        "result": "...", "passed": true,  "severity": "low"  },
    { "test": "External Reporter Authorization", "result": "...", "passed": true, "severity": "med" }
  ],

  "AiAnalysis": {
    "summary":              "Your DMARC is at p=reject with pct=100 — full enforcement...",
    "quick_recommendations": ["Publish BIMI...", "Tighten sp=..."],
    "security_assessment":   [{ "title": "...", "description": "...", "severity": "info | warning | critical" }],
    "fixes": [
      { "issue": "...", "kind": "dns_txt | dig", "host": "_dmarc.example.com", "snippet": "v=DMARC1; ..." }
    ]
  }
}
09 · USE CASES

How teams use DMARC Checker

Six patterns we see most often:

DMARC rollout monitoring (Operations)

Cron the API against your domains. Alert on grade regression (A → B → C), when the effective-enforcement score drops, or when `rua=` disappears. Catches well-intentioned 'temporary' rollbacks that get forgotten.

Bulk-sender compliance (Compliance)

Google/Yahoo 2024 and Microsoft 2025 bulk-sender rules mandate a published DMARC policy. Read the compliance flags from `data.compliance` — hard-fail your deploy pipeline if any sending domain regresses below the threshold.

Vendor email-auth diligence (Procurement)

Evaluating a SaaS vendor that will send mail on your behalf. Check their existing DMARC grade before onboarding. A vendor stuck at grade D for years tells you something about their security culture.

M&A email-security audit (Diligence)

Acquiring a company. Grade distribution across their sending domains is a direct signal of post-acquisition work. Most acquisitions inherit `p=none` (grade D) everywhere.

Anti-phishing incident response (Security)

A phishing campaign is using your domain. Verify grade A — and if not, this is the incident that motivates getting there. The Rollout tab shows exactly what step to publish next.

BIMI enablement (Marketing)

Marketing wants the logo-in-inbox. BIMI eligibility chip lights up green the moment `p=quarantine`/`reject` at `pct=100` is deployed. Read the flag; stop hunting through vendor docs.

10 · QUESTIONS

Common questions

  • How is the A–F grade computed? Grade is a function of policy strength × pct rollout × whether `rua=` is set. A = `p=reject; pct=100; rua=` set. B = `p=quarantine; pct=100; rua=` set. C = `p=quarantine`/`reject` but `pct<100`. D = `p=none` with `rua=`. F = no record, invalid syntax, multiple records, or `p=none` without `rua=`. The number underneath (effective enforcement) is `policyScore × (pct/100)`, range 0.0–2.0.
  • What is the cross-domain report authorization check? RFC 7489 § 7.1 requires that when your `rua=` mailbox is on a different domain than the published DMARC, the reporter must publish a `<yourdomain>._report._dmarc.<reporter>` TXT record starting with `v=DMARC1`. Without it, receivers silently discard your aggregate reports. We query this record for every external reporter and mark authorization pass/fail per URI.
  • What's the difference between p=none, p=quarantine, and p=reject? `p=none` is monitor-only — failing mail is delivered, you just get reports. `p=quarantine` tells receivers to mark failing mail as suspicious (typically delivered to junk/spam). `p=reject` tells receivers to block failing mail entirely. Production goal is `p=reject` at `pct=100` (grade A). Most domains stall at `p=none` (grade D) for years.
  • Why does pct=10 drop my grade from A to C? Because that's the real behaviour receivers implement. `p=reject; pct=10` means only 10% of failing mail is rejected; the other 90% gets the next-weakest treatment (quarantine). Effective enforcement is 0.2, not 2.0. Reading the tag as 'reject' hides the truth — the grade doesn't.
  • What bulk-sender rules do the compliance chips check? Google/Yahoo 2024 (Feb 2024): senders over 5,000 messages/day need a published DMARC policy (`p=none` is the floor). Microsoft 2025 (May 2025): aligned with Google/Yahoo. BIMI: requires `p=quarantine` or `p=reject` at `pct=100`. All three chips light up green when your record meets the threshold.
  • What's the difference between adkim=r and adkim=s? Alignment strictness for DKIM. `r` (relaxed, default) — the DKIM signing domain can be any subdomain of the From domain. `s` (strict) — the DKIM signing domain must exactly match the From domain. Relaxed is correct for ~99% of setups. Strict is flagged medium-severity in our tests.
  • Why am I not receiving DMARC aggregate reports? Common causes: (1) `rua=` not present, (2) typo or invalid email, (3) receiving mailbox filtering DMARC reports as spam, (4) reporter is external and the `_report._dmarc.<reporter>` authorization record is missing — we surface this explicitly, (5) domain doesn't receive enough mail to trigger reports.
  • Can I publish multiple DMARC records? No — RFC 7489 explicitly forbids it. Multiple records at `_dmarc.<domain>` cause receivers to ignore the entire DMARC check, treating the domain as if no policy existed. Our 'Single DMARC Record' test surfaces this as a high-severity failure.
  • What is BIMI and how is it related to DMARC? BIMI (Brand Indicators for Message Identification) displays your brand logo next to authenticated mail in supporting clients. BIMI requires DMARC at `p=quarantine` or `p=reject; pct=100`. Without strict DMARC, BIMI does nothing. Our BIMI-eligible chip lights up the moment you cross the threshold.