Blog/Deliverability

DMARC p=reject Migration: From Monitoring to Full Enforcement

MR
Marcus Rodriguez
Jun 29, 2026

Your DMARC record is live at p=none and collecting reports. Now what? Here's how to climb to full enforcement without bouncing your own legitimate mail along the way.

Hero image for: DMARC p=reject Migration: From Monitoring to Full Enforcement

Updated Jun 29, 2026

TL;DR: A DMARC p=reject migration moves your published policy from p=none (monitor only) up to p=quarantine and then p=reject (block spoofed mail at the SMTP door). Do it in stages: fix every alignment failure at p=none first, ramp through quarantine, then enforce reject, watching aggregate reports at each step so no real source gets caught.

You already published SPF, DKIM, and a DMARC record. The record sits at p=none, quietly collecting aggregate reports, and now you're staring at the obvious question. When do you flip it to p=reject, and how do you do that without dumping your own cold email into spam folders?

That flip is what people mean by a DMARC p=reject migration. It isn't about creating records anymore, because you've done that part. It's about climbing the enforcement ladder, none to quarantine to reject, slowly enough that legitimate mail keeps flowing while spoofed mail gets blocked. Done carelessly, the migration is exactly how senders nuke their own deliverability. Done in stages, it's routine.

If you still need to build the records themselves, start with our SPF, DKIM, and DMARC authentication guide and come back here once p=none is live and feeding you reports. This post assumes the records exist and only walks the enforcement ramp.

Key Takeaways

  • A DMARC p=reject migration is a policy change, not a record build. You move the p= tag from none to quarantine to reject.
  • The migration protects other people from spoofed mail using your domain. Your own inbox placement is gated by alignment, not by how strict your policy is.
  • Never jump straight to p=reject. Fix every alignment failure visible in your aggregate reports at p=none first, or real mail gets rejected the moment you enforce.
  • Google requires bulk senders (around 5,000 messages a day to personal Gmail) to publish a DMARC record with a minimum policy of p=none. Reject is stricter and protects your brand from spoofing.
  • The pct tag has long been the staged-rollout lever, but the 2026 DMARCbis specification deprecates it in favor of a new t (testing) tag.

What a DMARC p=reject migration actually changes

The p= tag tells receiving mail servers what to do with a message that fails the DMARC check. There are three values, defined the same way in the original spec, RFC 7489, and the 2026 update, RFC 9989:

  • p=none: the domain owner requests no specific action. Failing mail is delivered as normal, and you just collect reports.
  • p=quarantine: the domain owner wants failing mail treated as suspicious. In practice that means the Junk or Spam folder.
  • p=reject: the domain owner wants failing mail refused outright, ideally during the SMTP transaction so it never reaches an inbox at all.

Migration is simply moving up that scale. So far, so obvious. Here's the part most guides skip, and it changes how you think about the whole project.

Enforcement protects other senders' recipients from people who spoof your domain. It does not, on its own, lift your own cold email into the primary inbox. Your deliverability is decided by whether your mail passes DMARC, which comes down to authentication and alignment, not by whether your policy says none or reject. A perfectly aligned campaign sails through at p=none. A misaligned one still fails at p=reject, except now it bounces instead of landing.

So why migrate at all? Three honest reasons:

  1. Anti-spoofing. At p=reject, a scammer can't send invoice fraud or phishing "from" your domain and have it accepted. That protects your brand and the prospects you're trying to win.
  2. Bulk-sender compliance and trust signals. Google and Yahoo expect a published policy and proper alignment from bulk senders, and a domain at enforcement reads as a serious operator rather than a throwaway.
  3. Unlocking features that require enforcement. Inbox-logo programs like BIMI only work once your domain is at enforcement (typically p=quarantine with full coverage, or p=reject). More on that in our BIMI setup guide for cold email senders.

Keep that framing in mind. The migration is mostly a security and trust exercise. The deliverability win comes from the alignment work you do along the way, not from the word reject itself.

DMARC quarantine vs reject: what each policy does to failing mail

If you only remember one comparison, make it this one. The gap between quarantine and reject is the difference between "filed as junk" and "refused at the door."

Policy

What the receiver does with a failing message

Where the message ends up

Recoverable by recipient?

p=none

Nothing DMARC-specific; normal filtering still applies

Wherever the receiver's spam engine sends it

Yes

p=quarantine

Treats it as suspicious

Junk / Spam folder

Yes, recipient can fish it out

p=reject

Refuses during the SMTP transaction

Bounced, never delivered

No

Microsoft documents the receiver side cleanly: a p=reject failure produces an SMTP rejection (550 5.7.1), tagged action=oreject in the Authentication-Results header, while p=quarantine lands the message in Junk.

For a spoofing attacker, that distinction matters. At quarantine, the fraudulent message still reaches the victim's mailbox, just in a folder they might still open. At reject, it's gone. That's why most security-minded senders treat quarantine as a stepping stone, not a destination. The honest counterpoint: quarantine is genuinely safer to live at while you hunt down a stubborn legitimate source, because a false positive gets junked rather than bounced. Plenty of real-world domains sit at p=quarantine for months before the final step, and that's fine.

Before you change the policy, get a clean baseline at p=none

This is the gate that decides whether your migration is boring or painful.

While your record sits at p=none, receivers send you aggregate (RUA) reports: daily XML summaries of every source sending mail under your domain, whether each one passed or failed, and how it aligned. Your job before touching the p= tag is to read those reports until you can account for every legitimate source and confirm it passes DMARC.

The fields you care about live in the <policy_evaluated> block of each report: the <spf> and <dkim> results show whether a source aligned, not just whether it authenticated, as Microsoft's DMARC guide explains. A source can pass raw SPF and still fail DMARC because the domains don't align. That gap is the single most common reason a migration goes wrong.

I won't reproduce the full XML walkthrough here, because our sibling post on reading DMARC aggregate reports does that field by field. The migration gate is simpler than the parsing: do not advance the policy until several consecutive weeks of reports show close to 100% of your real mail passing DMARC, with every unknown high-volume source either identified and fixed or confirmed as spoofing you'd be happy to block.

A practical checklist before you move off p=none:

  • Every mailbox provider you actually send from (your cold-outreach inboxes, your CRM, your transactional service, your newsletter tool) appears in reports as aligned and passing.
  • No surprise "shadow IT" sender is producing legitimate mail that fails. Finance apps, e-signature tools, and helpdesk platforms are the usual culprits.
  • Your aggregate report volume has stabilized, so you're confident you've seen a representative slice of your sending, including monthly or quarterly senders.

Fixing DMARC alignment failures before you enforce

Alignment is where reject migrations live or die, so this section is the one to slow down on.

DMARC passes when SPF or DKIM both authenticates and aligns. Alignment means the domain in the visible From header matches the domain that SPF or DKIM verified. By default both checks run in relaxed mode (the adkim and aspf tags default to r), so the organizational domains only need to match, and subdomains are allowed, per RFC 7489. Strict mode (s) demands an exact match. For cold email, relaxed is almost always what you want.

Here are the alignment failures that bite during migration, and how to clear each one. This is adapted from Microsoft's documented failure scenarios:

Symptom in reports

Root cause

Fix

SPF authenticates but SPF alignment fails

A third-party service sends with its own domain in the MAIL FROM (envelope sender)

Set a custom MAIL FROM / Return-Path on your own domain at that service, or rely on DKIM alignment instead

DKIM authenticates but DKIM alignment fails

The service signs with d=theirdomain.com, not yours

Configure custom DKIM signing at the service so it signs with your domain

Both fail intermittently for forwarded mail

Forwarding rewrites the envelope and can break the DKIM body hash

Accept some forwarding loss, or have the forwarder act as a trusted ARC sealer

Subdomain sender fails under strict alignment

aspf=s or adkim=s is set and the From is on a different subdomain

Switch to relaxed (r), or make the From address match the signing subdomain

Work the list until your reports are clean. The test is brutal but simple: any legitimate source still failing DMARC when you flip to p=reject will have its mail rejected. A misconfigured invoicing tool you forgot about becomes a pile of bounced invoices on day one of enforcement. Fix it at p=none, where the only consequence is a line in a report.

The staged rollout ladder, step by step

Once your baseline is clean, the ramp itself is methodical. Microsoft's own rollout guidance maps the path, and it's the pattern I'd follow on any cold-email domain:

  1. Sit at p=none and monitor. You've done this. Confirm the reports are clean per the section above.
  2. Move to p=quarantine. Now failing mail gets junked instead of delivered. Watch your aggregate reports closely for a week or two. If a legitimate source you missed shows up failing, its mail is recoverable from Junk, so you have breathing room to fix alignment.
  3. Optionally ramp the percentage. If you're nervous, apply the policy to a fraction of failing mail first using the pct tag, then widen it. Microsoft suggests increments like pct=10, 25, 50, 75, 100. More on the mechanics and the 2026 caveat below.
  4. Move to p=reject. After quarantine runs clean, advance to full enforcement. Failing mail now bounces. Keep monitoring, because this is the step with no safety net.
  5. Confirm coverage at pct=100 (or no pct tag, which defaults to 100). You're done when the policy applies to all failing mail and your reports show no legitimate casualties.

A useful habit: start the whole ramp on a low-volume domain or a sending subdomain before you touch your primary brand domain. If something breaks, it breaks where it costs the least. Our guide on subdomain vs root domain for cold email covers why outreach usually belongs on an isolated subdomain in the first place.

The DMARC pct tag staged rollout (and the DMARCbis change you need to know)

The pct tag is the classic staged-rollout lever, and there's an important 2026 update here, so this is worth getting right.

Under the original spec, pct is an integer from 0 to 100, defaulting to 100, that tells receivers what percentage of failing mail to apply the policy to. Set p=quarantine; pct=25 and roughly a quarter of failing messages get junked while the rest pass through normal filtering. It lets you dip a toe in before committing.

One nuance trips people up. When you're at p=reject with pct under 100, the messages not selected for rejection aren't delivered normally. They're treated as though quarantine applied, as RFC 7489 specifies. So p=reject; pct=50 means "reject half, quarantine the other half," never "reject half, deliver the other half." During a reject ramp, your non-sampled failing mail is still being filtered hard.

Now the update. In May 2026, the IETF published the revised DMARC specification as three documents, RFC 9989, RFC 9990, and RFC 9991, moving DMARC to the Standards Track. That revision (long known as DMARCbis) deprecates the pct tag along with rf= and ri=. The working group found that receivers applied pct inconsistently, and that values other than 0 or 100 behaved unpredictably across the ecosystem.

The replacement is a new t (testing) tag. Set t=y and you're telling receivers to apply the policy one level below what p= states, without changing the From handling, so you can validate before full enforcement, per RFC 9989. In plain terms:

  • p=reject; t=y behaves like quarantine until you're confident, then you drop t=y.
  • p=quarantine; t=y behaves like none.
  • The old pct=0 maps to the new t=y; if you're already at pct=100, you can just drop the pct tag.

What does this mean for your migration today? Practically, major receivers honored pct for a decade and don't drop that support overnight, so a pct ramp still works in mid-2026. But the direction is clear. If you're configuring a fresh migration now, lean on the none to quarantine to reject policy steps as your primary safety mechanism, use t=y to test a level rather than building elaborate percentage schedules, and treat pct as a legacy lever on its way out.

A DMARC p=reject migration timeline you can follow

There's no universal duration, because it depends on how many sources you send from and how clean your reports start out. But here's a sane default pace for a typical cold-email domain. Adjust the dwell times based on what your reports show, never the calendar.

Phase

Policy

What you're doing

Typical dwell

Baseline

p=none

Collecting reports, identifying every source

2 to 4 weeks

Fix-up

p=none

Repairing each alignment failure until reports are clean

As long as it takes

Soft enforce

p=quarantine

Failing mail junked; watch for missed sources

2 to 4 weeks

Full enforce

p=reject

Failing mail bounced; final monitoring

Ongoing

If your domain only sends from one or two well-aligned sources, you can compress this to a few weeks. If you discover a tangle of marketing tools, CRMs, and helpdesk systems all sending under your domain, take longer. The cost of moving slowly is a few extra weeks of spoofable mail. The cost of moving too fast is bounced invoices and missed replies.

Subdomains, forwarding, and parked domains

Three edge cases deserve a quick word, because they catch people mid-migration.

Subdomains. A DMARC record on your root domain automatically covers subdomains that don't have their own record. You can set a separate policy for all subdomains with the sp tag, which defaults to whatever p says if it's absent, as defined in RFC 7489. DMARCbis also adds an np tag for non-existent subdomains, useful for shutting down spoofing of subdomains you never created. A common pattern: keep the root at p=reject for protection while you ramp a brand-new sending subdomain through its own none to quarantine to reject cycle.

Forwarding. Forwarded mail frequently breaks SPF alignment and can break DKIM if the body is modified. That's normal, and it's a reason not to panic when a small slice of failures shows up from mailing-list or forwarder IPs. Lean on DKIM alignment (it survives forwarding when the body is untouched) and let trusted forwarders ARC-seal where possible.

Parked and unused domains. If you own domains that send no mail, publish v=DMARC1; p=reject; on them immediately. There's nothing to ramp, because no legitimate mail exists to break. You're simply telling the world that nothing should ever claim to be from that domain.

After you reach p=reject: what to maintain

Hitting p=reject isn't a finish line, it's a state you have to hold. New tools get added, services change their signing, and a quietly broken source can start failing months later.

Keep these running:

  • Read your aggregate reports on a schedule. Weekly during the migration, then at least monthly once stable. New failing sources are your early warning. The reading DMARC aggregate reports guide is your reference.
  • Watch reputation, not just policy. Enforcement protects against spoofing, but your own placement still rides on spam rate and engagement. Google wants bulk senders below a 0.10% user-reported spam rate and treats 0.30% as the danger line. Track it through our domain health monitoring workflow.
  • Add the layers that enforcement unlocks. With p=reject live, you can pursue inbox-logo display via BIMI and harden transport encryption with MTA-STS and TLS-RPT.
  • Re-run a full check after any infrastructure change. Switching email providers, adding a marketing platform, or moving inboxes can reintroduce alignment failures. A periodic deliverability audit catches them.

If your migration is part of cleaning up after a reputation hit rather than a fresh setup, pair it with our guide on recovering a burned cold email domain, since authentication is one piece of that larger repair.

Common questions

Does moving to p=reject improve my cold email open rates?

Not directly. Your open rates depend on whether your mail passes DMARC (authentication plus alignment) and on your sender reputation, not on how strict your policy is. The alignment work you do to reach p=reject safely can help placement. The policy value itself mostly protects others from spoofing your domain.

Can I skip quarantine and go straight from none to reject?

You can, and on a single-source, perfectly aligned domain it's low risk. But for most senders it's a needless gamble. p=quarantine gives you a stage where a missed legitimate source gets junked (recoverable) instead of bounced (gone). Use it.

What's the difference between p=quarantine and p=reject in practice?

p=quarantine sends failing mail to the Junk folder, where a recipient could still retrieve it. p=reject refuses failing mail during the SMTP transaction, so it bounces and never arrives. Reject is the stronger anti-spoofing setting; quarantine is the safer place to pause during migration.

Is the DMARC pct tag still safe to use in 2026?

For now, yes, because major receivers still honor it. But the 2026 DMARCbis specification (RFC 9989) deprecates pct in favor of the new t=y testing tag. Build new migrations around the none to quarantine to reject policy steps and use t=y to test, treating pct as legacy.

Do I need p=reject just to send cold email through Gmail?

No. Google's bulk-sender rules require a published DMARC record with a minimum policy of p=none plus proper alignment. p=reject exceeds that minimum and protects your domain from being spoofed, which is why serious senders migrate to it anyway.

How long should I wait at each stage?

Let your reports decide, not the calendar. A common pace is 2 to 4 weeks at p=none to establish a baseline, however long it takes to fix every alignment failure, then another 2 to 4 weeks at p=quarantine before enforcing p=reject. Compress it if you send from few, clean sources; extend it if you find many.

Sources

Share the article

10x your leads, meetings and deals.

MailBeast scales your outreach campaigns with unlimited email sending accounts & warmup, smart sequences and AI-powered inbox management.

MailBeastSign up for free
Send Smarter. Land in Inboxes.
Close More Deals.
2026 MailBeast. All rights reserved.