DMARC policy: the migration path from p=none to p=reject
How to move your DMARC policy from p=none to p=reject safely: rua reports, pct= staged rollout, SPF/DKIM alignment, and why domains get stuck at none.
A DMARC policy tells receiving mail servers what to do with messages that claim to be
from your domain but fail authentication: do nothing (p=none), put them in spam
(p=quarantine), or refuse them (p=reject). Publishing the record is a five-minute
DNS change. Getting from p=none to p=reject without junking your own legitimate
mail is the actual project — and it's the project most domains never finish. The
majority of DMARC records in the wild sit at p=none indefinitely, which provides
monitoring data and satisfies checkbox requirements but blocks precisely zero spoofed
mail.
What a DMARC record contains
DMARC lives in a TXT record at _dmarc.<yourdomain>:
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; pct=25; rua=mailto:[email protected]; adkim=r; aspf=r; sp=reject"
| Tag | Meaning |
|---|---|
p= | Policy for the domain: none, quarantine or reject. |
sp= | Policy for subdomains, if different from p=. |
pct= | Percentage of failing mail the policy applies to (default 100). |
rua= | Where to send aggregate reports. |
ruf= | Where to send failure (forensic) reports — sparsely supported. |
adkim= / aspf= | DKIM/SPF alignment mode: r relaxed (default) or s strict. |
A message passes DMARC if either SPF or DKIM passes and aligns — meaning the
domain that passed matches the domain in the visible From header. With relaxed
alignment, an organisational-domain match suffices (mail.example.com aligns with
example.com); with strict, it must match exactly. Relaxed is the right default for
almost everyone; strict alignment mostly creates surprises when a subdomain or an ESP
return-path enters the picture.
The either/or is the crucial design decision. SPF breaks under forwarding; DKIM doesn't. So a well-set-up sender passes DMARC via DKIM even when a forwarder wrecks SPF — which is why getting DKIM signing right for every sending service is the real prerequisite for enforcement.
Step one: p=none with reporting
Start here, but understand what it is: a monitoring tap, not a policy.
v=DMARC1; p=none; rua=mailto:[email protected]
The rua address receives aggregate reports — XML files, typically daily, from
each participating receiver (Google, Microsoft, Yahoo and most large providers send
them). Each report says: these IPs sent mail as your domain, this many messages, here
are the SPF/DKIM/alignment results. Raw XML is miserable to read at volume, so most
teams feed it into a parsing tool.
ruf failure reports were meant to provide per-message forensic detail, but privacy
concerns mean very few receivers send them. Don't build your plan around ruf.
Spend a few weeks (a month is typical; longer if you have monthly billing runs or quarterly newsletters) answering one question from the aggregate data: what legitimate sources are failing alignment? Common finds: the CRM nobody mentioned, an office printer that emails scans, a regional office's marketing tool, internal apps relaying through a provider without DKIM. Fix each one — usually by setting up DKIM signing with the service, occasionally by adding it to SPF with an aligned return-path.
Step two: quarantine, staged with pct=
Once the report data shows your known-legitimate sources passing, move to enforcement gradually:
v=DMARC1; p=quarantine; pct=10; rua=mailto:[email protected]
pct=10 asks receivers to apply quarantine to only 10% of failing messages, leaving
the rest at none. Ratchet it — 10, 25, 50, 100 — over a few weeks, watching the
reports between each step. If a forgotten sender surfaces, only a fraction of its
mail was junked while you fix it. (One quirk worth knowing: pct applies the next
lower policy to the remainder, so p=reject; pct=50 quarantines the other half
rather than ignoring it.)
A note on quarantine as a destination: it means "treat with suspicion", which in practice means the spam folder. Users do occasionally fish things out of spam; nothing comes back from a reject. That makes quarantine the right place to pause and soak for a while.
Step three: reject
v=DMARC1; p=reject; rua=mailto:[email protected]; sp=reject
p=reject is the destination — it's the only policy that actually stops spoofed mail
from being delivered. Keep rua reporting forever: new sending services will be
added by people who've never heard of this project, and the reports are how you find
out before the complaints do.
Set sp= deliberately. Without it, subdomains inherit p=, which is usually what
you want — attackers happily spoof billing.example.com if the apex is locked down
but subdomains aren't. If specific subdomains send mail through services you can't
align yet, that's a reason to fix those services, not to leave sp=none as a
permanent loophole.
Why domains get stuck at p=none — and what it costs
The stall pattern is consistent. p=none got published to satisfy a deliverability
checklist or the Google/Yahoo bulk-sender requirements (which mandate DMARC at
minimum p=none for senders of 5,000+ messages/day). The aggregate reports go to a
mailbox nobody reads. Moving to enforcement requires chasing down every team's
sending tools, which is organisational work, not DNS work. So it never happens.
What it costs:
- Spoofing protection: none. At
p=none, a forged invoice from your exact domain sails through DMARC with no policy consequence. Domain spoofing for phishing and invoice fraud is precisely what enforcement exists to stop. - Deliverability signal: weakened. Receivers increasingly factor enforcement into reputation; an enforced policy is a stronger trust signal than a monitoring-only one.
- The reports rot. The visibility
p=nonewas supposed to provide only has value if someone acts on it.
The honest framing: p=none is a starting line that most domains have mistaken for a
finish line.
DomainOps monitors DMARC records across your domain portfolio — policy, alignment settings, and whether the record breaks or gets downgraded — alongside SPF and DKIM checks, with alerts when something changes. To see where your domain stands today, run the free email auth audit.