pct= is Deprecated in RFC 9989: Migrate Your DMARC Record
RFC 9989, published May 20, 2026, removes pct= from the DMARC policy model. Receivers are no longer required to honor it, and for most large receivers like Google and Microsoft, the sampling guarantee was already being ignored in favor of their own risk-scoring logic. If your record still contains pct=50 or pct=25, remove it and use the staged policy approach instead: start at p=none to collect reports, move to p=quarantine once alignment is clean, then advance to p=reject when you're above 98% sustained alignment.
What pct= was supposed to do
The pct= tag was designed as a rollout safety valve. It told receiving mail servers to apply your DMARC policy (p=quarantine or p=reject) to only X% of messages that failed alignment. The remaining messages would be treated as if p=none were set, delivered normally but still reported.
The idea: if your pct=25, you could move to p=reject while only affecting a quarter of failing mail. A way to test enforcement without the full blast radius.
In practice, receivers implemented it inconsistently from the beginning. Google and Microsoft have been largely ignoring pct= for years, applying their own risk-scoring logic instead of the sampling percentage. The "training wheel" often wasn't actually engaged, even when you thought it was. You could have pct=10 in your record and Gmail would reject the full volume of failing mail anyway.
Why RFC 9989 removed it
RFC 9989 codified what large receivers were already doing: not reliably honoring pct=. Rather than leaving a spec feature in place that nobody was implementing correctly, the committee removed it. This isn't a breaking change in practice for most senders. The behavior at major receivers was already undefined. The spec is catching up to reality.
Backward compatibility means a pct= tag in your existing record won't cause errors. Receivers will simply ignore it. But you can no longer rely on it to limit enforcement scope during a rollout.
The right rollout approach in 2026
The staged policy approach replaces pct=-based sampling, and it's actually more reliable, because you're testing real enforcement on your full mail stream rather than a sample that receivers may or may not honor.
Step 1: Start at p=none
v=DMARC1; p=none; rua=mailto:your-dmarcdrift-address
This collects aggregate reports without enforcing anything. Run here for 2-4 weeks. You're looking for your alignment rate across all sending sources. Any service that sends email on behalf of your domain should show up in the reports.
Step 2: Move to p=quarantine when alignment is clean
v=DMARC1; p=quarantine; rua=mailto:your-dmarcdrift-address
Once you're seeing 95%+ alignment sustained over 2-4 weeks, move to p=quarantine. Failing messages go to spam instead of inbox. This is enough to make spoofing significantly harder, and it surfaces any legitimate senders you missed at p=none. Watch for a week or two. If nothing breaks, you're ready for the last step.
Step 3: Move to p=reject
v=DMARC1; p=reject; rua=mailto:your-dmarcdrift-address
Failing messages are refused at the receiving server. This is the finish line. Sustained 98%+ alignment over 30 days before making this move.
This approach is safer than pct= sampling because you see problems across your full mail stream at each stage, not a sampled fraction. If a sending source is misconfigured, it shows up clearly in reports rather than being masked by sampling noise.
Before and after:
# Before (legacy pct= approach)
v=DMARC1; p=reject; pct=25; rua=mailto:...
# After (if you're not ready for full reject yet)
v=DMARC1; p=quarantine; rua=mailto:...
# After (if alignment is already clean)
v=DMARC1; p=reject; rua=mailto:...
How to know where you stand
Your aggregate reports tell you your alignment rate. For each report, you have message counts and policy_evaluated results showing whether DKIM and SPF passed alignment for each sending source.
If your alignment has been above 98% for 30 or more days across all senders, you're ready for p=reject. If it's 90-97%, p=quarantine is the right intermediate step, and you should be investigating which sources are pulling the rate down before tightening further.
DMARCdrift's domain health checklist now flags pct= as a deprecated tag. If your domain's health check shows a pct= warning, it means your record includes the tag and you should migrate using the approach above. The dashboard alignment chart shows you whether you're in the safe zone for a policy move.
The 5-minute fix
First, check what you have:
dig TXT _dmarc.yourdomain.com
Then decide:
-
No
pct=tag, orpct=100: Nothing urgent. Your record is already behaving as a full-enforcement record. You may want to removepct=100for cleanliness, but it has no functional effect. -
pct=50or similar withp=reject: You were counting on sampling to limit blast radius. That's gone. Either removepct=and stay atp=rejectif your alignment rate supports it (98%+), or drop back top=quarantinewithoutpct=until you're confident. -
pct=25withp=quarantine: You were being extra cautious. Now just usep=quarantinedirectly. The staged policy approach gives you the same safety with more visibility.
In all cases, keep your rua= address in place. The reports are what let you know when something breaks.
What about np=?
RFC 9989, published alongside RFC 9990, adds np=, the non-existent subdomain policy tag. Once you're at p=reject on your main domain, adding np=reject closes a gap: it explicitly tells receivers what to do with mail claiming to be from subdomains that don't exist (like phishing@nonexistent.yourdomain.com). Without np=, receivers fall back to your top-level p= value, which is usually fine, but explicit is better.
If you're curious about the full set of changes in the 2026 DMARC RFCs, the RFC 9989 post covers the np= tag and what else changed in the spec.
