praneeth@website:~$ dmarc --check
DMARC rollout plan and record checker
That record is where you are heading — full protection against anyone sending mail as your domain. Publishing it today would bounce your own invoices. Below is the staged route there, where every step that can affect real mail comes after one that cannot.
- checked against
- RFC 9989
- stages
- 7
- typical duration
- 2–4 months
- what we collect
- nothing
Nothing you type or paste is ever sent to this site — there is no server involved and no analytics. Looking up a domain is the one exception: that query goes straight from your browser to a public DNS resolver, asking the same public question any mail server does, and only when you press the button.
DMARC rollout plan
Prepared for yourdomain.com
Current version: https://praneeth.me/bin/dmarc
Checked against RFC 9989, 9990, 9991 and 9824.
Sends _dmarc.yourdomain to Cloudflare’s public DNS resolver
over HTTPS, from your browser. A DMARC record is public — this is the
same query any mail server makes. Nothing is sent to this site.
Checked in your browser. Never sent anywhere.
findings
Optional. Fills your domain and this address into every record below. Stays in this browser tab.
- 0 audit
- 1 monitor
- 2 fix
- 3 quarantine
- 4 reject
Before you start. This is a staged plan, not a checklist to do in one sitting. Getting from nothing to full protection normally takes months, and every stage that can affect real mail is deliberately preceded by one that cannot. Read the whole thing before publishing anything.
Phase 0 — Where are you now?
What this is. Find out what your domain already says before changing anything. Most domains have something — often set years ago by someone who has left, or added automatically by a mail provider.
What you do. Look up your domain, or paste a record you already have. Either way it is checked against RFC 9989 right here.
Prefer to look it up yourself
dig +short TXT _dmarc.yourdomain.com
# Windows
nslookup -type=TXT _dmarc.yourdomain.com No record change in this phase.
Before moving on. You can state
what your domain currently does with failing mail: nothing, quarantine,
or reject. If the record contains pct=, rf= or
ri=, note them — they were removed from the spec
and no longer do anything.
Phase 1 — Start watching, and close the doors that don't exist
What this is. Two things, neither of which can break your mail.
The first is asking mail providers to report to you — a daily summary of who is sending as your domain, including senders you have forgotten and anyone impersonating you. Nothing about how your mail is treated changes.
The second is shutting down subdomains that do not exist. If payroll.yourdomain.com has never existed, nothing legitimate can come from it — a name with
no DNS record cannot have SPF or DKIM. Technically these are names that return
NXDOMAIN: the DNS answer
meaning "no such name". Phishing uses invented subdomains precisely
because they have historically been unprotected. This is the safest
change in the whole process, which is why it happens now rather than at
the end.
v=DMARC1; p=none; np=reject; rua=mailto:[email protected] | tag | what it does |
|---|---|
| p=none | don't change how my mail is treated |
| np=reject | reject mail claiming to come from subdomains that don't exist in DNS (names returning NXDOMAIN) |
| rua= | send daily summary reports here |
Existing subdomains are untouched. sp= stays out of the record entirely. Subdomains that do exist
follow p=none and are left alone until reports show what actually
sends from them.
What you do
- Decide where reports go. Two paths:
- A reporting service (most people).
They give you an address for
rua=and handle the rest — follow their setup steps, not ours. dmarcian, Postmark DMARC and URIports all have free tiers that suit a single domain. Listed because “use a service” is useless advice on its own — not as endorsements, and none is affiliated with this site. - Your own mailbox. You will get XML attachments daily from dozens of providers. Workable for one domain with light mail; unreadable at volume.
- A reporting service (most people).
They give you an address for
-
Publish as a TXT record at
_dmarc.yourdomain.com. - Wait and read.
Before moving on.
- Reports are actually arriving.
- You can name every legitimate system sending as you — not just your mail provider, but the invoicing system, the CRM, monitoring alerts, the marketing platform, the printer.
- At least 2–4 weeks, and one full billing cycle. If you bill monthly and skip this, you will discover your invoices were failing on the day you start rejecting mail.
Reports aren't arriving
Give it a week. Some providers send once a day; a few take longer to start.
Check the obvious first. The
record must be at _dmarc.yourdomain.com, not on the domain itself. A typo in
rua= fails silently.
If you're using a reporting service and still see nothing, ask them — they publish the authorisation record on their side and can confirm it is in place.
If you pointed rua= at an address on a different domain
yourself — a personal address, or a mailbox on another domain you own —
that domain has to grant permission. Nothing tells you it is missing;
providers simply don't send:
yourdomain.com._report._dmarc.otherdomain.com TXT "v=DMARC1"
Not needed when rua= points at the same domain you are protecting.
Phase 2 — Fix what's failing
What this is. Reports now show legitimate senders failing. This phase fixes them. Your DMARC record doesn't change — you stay in watch-only mode while the real work happens elsewhere. This is usually the longest phase, and the record sits still throughout.
v=DMARC1; p=none; np=reject; rua=mailto:[email protected] What you do. For each failing sender, get SPF or DKIM passing and aligned. Aligned means the domain that authenticated matches the domain in the From: address. A sender can pass SPF and still fail DMARC by passing for the wrong domain — the most common source of confusion here.
You only need one of them
DMARC passes if SPF passes and aligns, or DKIM passes and aligns. Both is not required.
| SPF | DKIM | DMARC |
|---|---|---|
| pass, aligned | fail | pass |
| fail | pass, aligned | pass |
| pass, not aligned | fail | fail |
| pass, not aligned | pass, not aligned | fail |
Chase DKIM first. When mail is forwarded, SPF breaks — the forwarding server isn't in your SPF record, and nothing you publish fixes that. DKIM survives forwarding. A sender passing only SPF will fail intermittently in ways you can't resolve, so DKIM is where limited vendor-wrangling time is best spent. Keep SPF correct too; just don't rely on it alone.
Optional, for diagnosis
v=DMARC1; p=none; np=reject; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1 ruf= requests individual failure reports; fo=1 asks
for one whenever either check fails rather than only when both do.
These can contain message headers and sometimes body content belonging to
other people, and many providers won't send them at all for that reason. Turn
it off when you're done diagnosing.
Before moving on. A high, stable pass rate. Every remaining failure is one you have identified and are content to have blocked. No unexplained sources.
Phase 3 — Quarantine
What this is. Failing mail goes to spam instead of the inbox. Recoverable, which is why it comes before rejection.
What replaced the old percentage ramp.
Previously you ramped with pct=10, then 25, 50, 100.
pct= was removed and does nothing — leaving it in doesn't
slow anything down; receivers ignore it and apply your policy in full immediately.
The replacement is t=y, and its behaviour is easy to
misread:
it applies the policy one level below the one you published. It is not an off switch.
| record | what actually happens to failing mail |
|---|---|
| p=quarantine; t=y | nothing — treated as p=none |
| p=quarantine | quarantined |
| p=reject; t=y | quarantined |
| p=reject | rejected |
v=DMARC1; p=quarantine; t=y; np=reject; rua=mailto:[email protected] Nothing happens to your mail. Reports show exactly what would be quarantined. This is the only genuinely zero-impact step in the ramp. Sit here 1–2 weeks.
v=DMARC1; p=quarantine; np=reject; rua=mailto:[email protected]
Dropping t=y is the moment real mail is first affected.
Holding subdomains back
If Phase 1's reports showed an existing subdomain still failing, it
would otherwise be dragged to quarantine alongside the parent. sp=none holds it:
v=DMARC1; p=quarantine; sp=none; np=reject; rua=mailto:[email protected] Only use this if reports showed a subdomain sending. Don't set it because one might.
Before moving on. 2–4 weeks at full quarantine, no legitimate mail affected, no new failing sources.
Phase 4 — Reject
What this is. Failing mail is refused outright rather than spam-foldered. Nobody can retrieve it.
v=DMARC1; p=reject; t=y; np=reject; rua=mailto:[email protected] Failing mail is quarantined — the same disposition as Phase 3b. Because the effect on mail is identical, moving from 3b to 4a carries no new risk; what changes is what you are signalling and what the reports show you about rejection impact. Sit here 1–2 weeks.
v=DMARC1; p=reject; np=reject; rua=mailto:[email protected] Bringing subdomains along
Once reports show existing subdomains are clean, drop sp= so
they inherit
p=reject, or state it explicitly:
v=DMARC1; p=reject; sp=reject; np=reject; rua=mailto:[email protected] What this does and doesn't give you. This is the strongest protection against someone sending mail directly as your domain. It does not fix indirect flows — mailing lists and forwarding services — which must be understood before you get here, not after. See the scenarios below.
Before moving on. There is no moving on. Keep reading reports; new senders get added over time and each will fail until aligned.
Refinements
Optional. You can run a fully protected domain without any of these.
adkim= / aspf= — how exact alignment must be
Default r (relaxed): mail.yourdomain.com counts as matching
yourdomain.com. s (strict) requires an exact match.
v=DMARC1; p=reject; adkim=s; aspf=s; np=reject; rua=mailto:[email protected] Strict alignment most often breaks SaaS vendors, because they sign with their own subdomain:
From: alerts@yourdomain.com
DKIM: d=mailer.yourdomain.com
relaxed → matches, passes
strict → doesn't match, fails
Only pursue strict if you specifically need to stop subdomains
authenticating for the parent. Review every vendor first, and introduce
it back at p=none and watch — never as an edit to a live
p=reject record.
fo= — which failures generate a report
Only does anything when ruf= is set. 0 (default)
both must fail; 1 either fails; d DKIM failed; s SPF failed. Combine with a colon: fo=d:s. fo=1 is the useful one.
ruf= — failure reports
Covered in Phase 2. A diagnostic tool, not a permanent setting.
psd= — public suffix domains
Only relevant if other organisations register names under your domain
— a registry, or something like co.uk. Values y, n,
u (default). If you are not a registry, ignore it.
Multiple report destinations
Comma-separated; every external domain needs its own authorisation record (see “Reports aren't arriving” above):
rua=mailto:[email protected],mailto:[email protected] Tags that no longer exist
pct=, rf=, ri=. Remove them. pct=
especially, because it implies a gradual rollout that isn't happening.
Scenarios
A domain that sends no mail at all
Tempting to jump straight to reject, but “we don't use this domain” is exactly the belief that turns out wrong — usually a campaign someone ran years ago. Run a shortened Phase 1 (two weeks) to confirm, then go straight to reject:
v=DMARC1; p=reject; sp=reject; np=reject; rua=mailto:[email protected] Pair it with an SPF record authorising nothing, and a null MX:
yourdomain.com. TXT "v=spf1 -all" yourdomain.com. MX 0 . A subdomain with its own DMARC record
_dmarc.news.yourdomain.com overrides the parent completely — your
sp= is ignored for it. Check for these before assuming the parent
is in charge.
Mailing lists
Lists that modify the subject or add a footer break DKIM, and mail
arrives from the list server so SPF doesn't align. At p=reject, your posts to those lists may be rejected. Nothing on your side fixes
it; well-run lists rewrite the From: address to handle it.
Third-party senders you can't configure
If a vendor can't do aligned DKIM for your domain: have them send from
their own domain, give them a subdomain with its own DMARC record set to none, or replace them. No tag makes unaligned mail pass.
The whole path
| phase | record | effect on mail | duration |
|---|---|---|---|
| 0 | no change | none | one sitting |
| 1 | p=none; np=reject; rua=… | none | 2–4 wks, min. 1 billing cycle |
| 2 | unchanged | none | weeks to months |
| 3a | p=quarantine; t=y; np=reject; rua=… | none | 1–2 weeks |
| 3b | p=quarantine; np=reject; rua=… | quarantined | 2–4 weeks |
| 4a | p=reject; t=y; np=reject; rua=… | quarantined | 1–2 weeks |
| 4b | p=reject; np=reject; rua=… | rejected | ongoing |
Before you rely on any of this
This is guidance, not professional advice. It is provided as-is, with no warranty of any kind. You are responsible for your own mail flow and for every DNS change you publish. If mail matters to your organisation commercially, legally or operationally, involve someone accountable for it before enforcing.
Rejection cannot be undone. At
p=reject, mail that fails is refused at the receiving server
and is gone — not in a spam folder, not recoverable. Every phase
before it exists to make sure that only mail you intend to block gets
blocked.
What is checked, and what isn't. The checker in Phase 0 reads one DMARC record — looked up or pasted — and reports what RFC 9989 makes of it, including which phase that record sits at. That is the whole of it. It does not inspect your mail flow, verify your senders, read your aggregate reports, or know whether the work behind a published policy was ever done. The phases are the same for everyone; only the findings are about you.
The durations are convention, not specification. Nothing in RFC 9989 mandates a timeline. The week counts here reflect common practice; the “one full billing cycle” rule is the one worth treating as a hard minimum, because monthly and quarterly senders are what people miss.
DNS changes are not instant. Existing TTLs mean receivers may act on your previous record for hours after you publish a new one. Lower the TTL before a change if you need it to take effect predictably, and never assume an edit is live because it resolves for you.
np= may silently not apply. It relies
on receivers seeing NXDOMAIN for a non-existent subdomain. Some DNSSEC-signed
providers — Cloudflare, AWS Route 53, NS1 and Azure DNS among them
— answer with compact denial of existence (RFC 9824) instead, returning
NOERROR with an NXNAME-bearing NSEC record. A receiver checking strictly for
NXDOMAIN concludes the subdomain exists and skips your policy. Setting np=reject
still costs nothing; just don't treat it as airtight.
Your provider's instructions win. If a reporting service, mail platform or registrar tells you something different about their own setup, follow them. This plan cannot know how your specific vendors behave, and no vendor named anywhere on this page is affiliated with or endorsed by this site.
Written against RFC 9989 (May 2026), which replaced RFC 7489, together with RFC 9990, RFC 9991 and RFC 9824. Specifications change and receiver behaviour lags them. Check the current RFC before treating any statement here as authoritative.