Moving from DMARC p=none to p=reject without killing legitimate email
You set up DMARC six months ago. The record says p=none. You’re getting reports. Life is fine.
Except it isn’t. p=none means receivers are doing absolutely nothing when someone sends a spoofed email from your domain. Phishing attacks, business email compromise, supply-chain scams — all of them can use your domain with zero resistance.
This guide walks you through moving to enforcement without the dreaded “we stopped getting customer emails” phone call.
Why p=none is a starting point, not a destination
When you set p=none, you told every mail server in the world: “If someone sends email pretending to be me and fails authentication, please log it and tell me, but deliver it anyway.”
That’s useful for discovery. It’s dangerous to stay there.
The goal is p=reject: you’re asking receivers to drop, entirely, any mail that can’t pass DKIM or SPF alignment. Receivers aren’t obligated to honor that request (more on that in Step 4), but the large majority do — which makes your domain nearly worthless for phishing.
The risk of rushing straight to p=reject is that you’ll reject your own legitimate email — the newsletter platform you forgot to authorize, the legacy CRM your marketing team uses, the automated invoice system that IT set up three years ago.
The solution is a methodical transition, not a leap.
Step 1 — Read your reports before you touch anything
Spend a week actually reading your DMARC aggregate reports. You want to answer one question: are any legitimate senders currently failing?
Look for patterns in the failure data:
- High volume from a single IP — probably a sending service you haven’t authorized
- Consistent SPF pass, DKIM fail — the sender authenticates via SPF but hasn’t set up DKIM signing
- Low volume scattered failures — likely forwarding artifacts or old bounce handlers, usually safe to ignore
If you see a domain you recognize (sendgrid.net, amazonses.com, mailgun.org) in the failure list, that service needs to be added to your SPF record and configured to sign with DKIM before you move to enforcement.
If you see IPs you don’t recognize sending your domain, that’s exactly what DMARC enforcement is designed to stop.
Step 2 — Fix authentication for every legitimate sender
For each legitimate service that’s failing, do two things:
Add them to SPF. Your SPF record lives at your root domain as a TXT record. Add the service’s include:
v=spf1 include:_spf.google.com include:sendgrid.net include:amazonses.com ~all
One trap: SPF has a limit of 10 DNS lookups. If you have many services, check your lookup count before adding more includes. DMARC Guardian’s DNS tab shows your current count. If you’re near the limit, consider a hosted SPF service that flattens the includes into a single list of IPs — see SPF permerror: why adding one SaaS tool breaks your email authentication.
Configure DKIM for each service. Every major email platform (SendGrid, Amazon SES, Mailchimp, Postmark) has a guide for generating a DKIM key pair and publishing the public key in DNS. Log into each platform and follow their DKIM setup docs. It typically involves adding a CNAME or TXT record at something like s1._domainkey.yourdomain.com.
After each change, wait 24 hours and check your DMARC reports again. The failing sender should start showing passes.
Step 3 — Move to p=quarantine first
Don’t jump straight to p=reject. Move to p=quarantine first — but skip pct=. If you’ve read an older guide (including an earlier version of this one), it likely told you to dial up a percentage. That advice is now wrong: the current DMARC standard, RFC 9989, removed the pct tag entirely (Appendix A.6, “Removal of the ‘pct’ Tag”). The working group’s own reason: “Operational experience showed that the ‘pct’ tag was usually not accurately applied, unless the value specified was either 0 or 100 (the default), and the inaccuracies with other values varied widely from one implementation to another.” If you publish pct=10 today, a current-standard receiver is required to ignore it as an unrecognized tag (§4.7) — it does nothing, and it gives you false confidence that only a tenth of your mail is at risk.
What replaced it is the t tag (§4.7) — a binary test-mode switch, not a dial:
v=DMARC1; p=quarantine; t=y; rua=mailto:your-rua-address
t=y asks a receiver honoring it to apply the policy one level weaker than published, for every failing message — not a random slice of them. With p=quarantine; t=y, that means failing mail is treated as if the policy were still p=none: nothing gets quarantined while you watch. Be precise about what the report actually tells you here: the row’s disposition field reports what was applied — none, per the test-mode downgrade — not the stricter policy you’re testing. Don’t go looking for quarantine there; it won’t be. What you get instead is the pieces to reconstruct it: policy_published still shows the policy you actually set (p=quarantine), and RFC 9990 §3.1.6 defines an explicit override reason, policy_test_mode, that every affected row is tagged with — the combination tells you “this message would have been quarantined, but wasn’t, because you’re in test mode.” You get full visibility into every failing message and zero disruption — which is a strictly better guarantee than pct=10 ever gave you, since pct never reliably controlled which slice of mail was sampled.
Before moving to quarantine, verify these thresholds:
- SPF + DKIM pass rate is above 99% for legitimate senders
- No legitimate sender appears in the failure list
- Your DMARC reports have been clean for at least 2 weeks
Monitor for two things:
- Legitimate email landing in spam — check your own spam folder and ask colleagues to do the same for a week
- Report failures jumping suddenly — a spike means something changed, investigate before proceeding
After one to two weeks of p=quarantine; t=y reports showing no unexpected failures, remove the t=y flag so quarantine actually takes effect:
v=DMARC1; p=quarantine; rua=mailto:your-rua-address
Run this for another one to two weeks before touching p=reject. Rushing this phase is how teams break legitimate email.
Step 4 — Promote to p=reject, the same way
Once real p=quarantine (no t=) has run cleanly for two weeks, repeat the same pattern one level up. Publish p=reject; t=y first:
v=DMARC1; p=reject; t=y; rua=mailto:your-rua-address
t=y softens the applied action back down to quarantine while you confirm reject is safe — same policy_test_mode visibility, same zero-disruption safety net, one rung higher on the ladder. After another clean one-to-two-week window with no legitimate sender appearing in the failure list, remove t=:
v=DMARC1; p=reject; rua=mailto:your-rua-address
At this point, unauthorized senders using your domain get their messages dropped by receivers that honor the policy, before those messages reach anyone’s inbox. One honest limit worth stating plainly: RFC 9989 §8 requires that “Mail Receivers MUST NOT reject messages solely on the basis of a ‘p=reject’ policy.” No receiver is obligated to enforce what you publish — p=reject is a request, not a guarantee. The large majority of receivers honor it in practice, but your DMARC reports are how you confirm that’s actually true for your traffic, not something to assume.
What to monitor after enforcement
Enforcement isn’t set-and-forget. Three things to watch:
New sending services. Every time the business adds a new tool that sends email (a helpdesk, a CRM, an automated invoice system), it needs to be authorized before it goes live. Make “add to SPF and configure DKIM” part of your SaaS onboarding checklist.
SPF record changes by third-party providers. Providers occasionally change their sending infrastructure and update their SPF includes. If a provider changes their include: mechanism, your SPF may need updating. DMARC reports will show you the failure before your users notice.
Forwarding artifacts. Email forwarding breaks SPF by design — the forwarded message arrives from the forwarder’s IP, not your authorized IP. If colleagues use external forwarders, they’ll see failures in your reports. These are usually low-volume and mostly harmless under p=reject (the forwarded message might land in spam at the destination), but they’re worth understanding. See Email forwarding breaks SPF and DMARC — here’s why.
The failure mode most teams hit
The most common reason teams stay stuck at p=none for years is not technical — it’s organizational. Someone set up DMARC on a Tuesday, got busy, and nobody owns the “move to enforcement” decision.
Fix this by assigning a specific deadline. “We will reach p=reject by [date].” Put it in a ticket. Work through the fixing and monitoring phases with that date in mind.
DMARC Guardian’s timeline charts make the monitoring phases faster because you don’t have to manually parse XML attachments. But the decision to enforce is yours.
A realistic timeline
| Phase | Duration | What you’re doing |
|---|---|---|
Discovery (p=none) | 4–8 weeks | Reading reports, identifying all senders |
| Fix legitimate senders | 1–2 weeks | SPF + DKIM for each service |
Quarantine, t=y (safety net) | 1–2 weeks | Full visibility via policy_test_mode, zero disruption |
Quarantine, enforced (t= removed) | 1–2 weeks | Confirming clean with quarantine actually applied |
Reject, t=y (safety net) | 1–2 weeks | Full visibility one level up, zero disruption |
Reject, enforced (t= removed) | Ongoing | Monitoring for new senders |
Total: roughly 8–16 weeks from committed start to enforced p=reject. This is not fast, but it’s safe. Rushing is how you break legitimate email.
If you’ve already been in p=none for months, your discovery phase is done — you can skip straight to fixing senders.
Rollback plan: Keep a copy of your previous DNS records. If legitimate email starts failing, you can revert to p=none within minutes. This is not a failure; it’s the reason you staged the rollout.
One last check before p=reject
Before you flip the switch, confirm these five things are true:
- All legitimate sending services have SPF includes and DKIM configured
- Your SPF record stays under 10 DNS lookups
- You have an RUA address actively receiving reports
- SPF + DKIM pass rate is consistently above 99.5% for legitimate traffic
- Someone on your team will check reports at least weekly
If all five are true, enforce. Your domain will be meaningfully harder to spoof the moment the DNS change propagates.