DMARC Policy: Moving from p=none to Quarantine to Reject Safely

Publishing a DMARC record with p=none is easy, and a lot of domains stop there. It satisfies the bulk sender requirements from Gmail and Yahoo, but it doesn't actually stop anyone from spoofing your domain. The protection starts at p=quarantine and is complete at p=reject.

The reason people stay at none is fear: switch to reject too early and your own invoices, password resets or support replies start disappearing. That fear is justified, but the fix is a staged rollout, not staying at none forever. This is the process I'd follow.

A quick refresher

DMARC tells receiving servers what to do with mail that claims to be from your domain but fails authentication. A message passes DMARC if either SPF or DKIM passes and aligns with the domain in the visible From header. If you want the full background, read SPF, DKIM and DMARC explained.

The three policies:

Policy What receivers do with failing mail Risk to your legit mail
p=none Deliver normally, just report None
p=quarantine Usually deliver to spam Misconfigured senders land in spam
p=reject Refuse the message at SMTP Misconfigured senders are blocked

Receivers treat your policy as a strong request rather than an absolute rule, but the large mailbox providers do honor it.

Stage 1: p=none with reporting

Start with monitoring. The key part is the rua tag, which is where receivers send daily aggregate reports:

_dmarc.example.com  TXT  "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"

A few practical notes:

  • Use a dedicated mailbox or a report processor. Aggregate reports are XML attachments, one per receiver per day. Reading them raw is miserable. A DMARC reporting service or an open-source parser turns them into a table of sending sources.
  • If the report address is on another domain, that domain must publish an authorization record (example.com._report._dmarc.otherdomain.com). Most reporting services handle this for you.
  • Skip ruf (forensic reports) unless you have a reason. Few large providers send them, and they can contain personal data.

You can build a starting record with the DMARC generator and confirm it's live with the DMARC checker.

Stage 2: read the reports and inventory every sender

Leave p=none running for a few weeks so you see monthly jobs like invoices and newsletters. Then go through the reports and list every source sending as your domain. You'll typically find:

  • Your main mailbox provider (Google Workspace, Microsoft 365)
  • Your marketing ESP (newsletters, campaigns)
  • Your transactional provider (password resets, receipts)
  • CRM and sales tools that send as your reps
  • Helpdesk (support replies)
  • Billing and invoicing platforms
  • Forgotten things: a website contact form, a monitoring tool, a printer that emails scans, an old server
  • Spoofers: IPs you don't recognize at all

For each legitimate source, write down whether it passes SPF, DKIM and, most importantly, whether either one aligns.

Stage 3: fix alignment for every legitimate sender

This is the real work. The usual problems and fixes:

Symptom in reports Cause Fix
DKIM pass, but d= is the vendor's domain Vendor signs with its own domain Set up custom DKIM for your domain in the vendor's settings
SPF pass, but for the vendor's bounce domain Return-Path is on the vendor's domain Set up a custom return-path/bounce domain, or rely on aligned DKIM
SPF fail from a known service Service not in your SPF record Add its include:, watch the 10-lookup limit
SPF permerror More than 10 DNS lookups Remove unused includes; move senders to subdomains
DKIM fail on forwarded mail Mailing lists or forwarders modify the message Usually acceptable; ARC helps at big receivers

Aligned DKIM is the more robust of the two because it survives forwarding, while SPF breaks whenever mail is forwarded. My rule: every sending service gets DKIM with d= on your domain (or a subdomain of it, since relaxed alignment is the default). SPF alignment is a bonus.

Check each service after you fix it with the DKIM checker and SPF checker, then wait for a few days of clean reports.

Stage 4: quarantine, ramped with pct

When the reports show that all your legitimate mail passes aligned, move to quarantine. The pct tag lets you apply the policy to a percentage of failing mail and treat the rest as the next policy down:

_dmarc.example.com  TXT  "v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc-reports@example.com"

A reasonable ramp is 25, then 50, then 100, with at least a week at each step while you watch reports and support tickets. If something you missed starts failing, only part of it lands in spam, and you have time to fix it.

One caveat: pct values other than 0 and 100 have never been applied very precisely by every receiver, and the DMARC spec revision in progress (DMARCbis) replaces pct with a simpler test flag. It's still widely supported today, but think of it as a soft ramp, not an exact dial.

Stage 5: reject

After a clean period at p=quarantine with pct=100 (or no pct, which means 100), switch to reject:

_dmarc.example.com  TXT  "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com"

Keep rua reporting on. New tools get added over time, and the reports are how you'll notice that the new helpdesk someone signed up for isn't aligned.

Subdomains and sp=

By default, subdomains inherit the parent's policy. The sp tag sets a separate policy for them:

_dmarc.example.com  TXT  "v=DMARC1; p=reject; sp=quarantine; rua=mailto:dmarc-reports@example.com"

Two common patterns:

  • Parent at reject, subdomains stricter or equal. Attackers love spoofing billing.example.com or other subdomains you've never used. If you don't send from subdomains, sp=reject closes that gap.
  • Sending subdomains with their own records. If marketing sends from news.example.com, give it its own _dmarc.news.example.com record. A subdomain's own record overrides sp.

Domains that never send mail at all should publish p=reject right away, along with an empty SPF record (v=spf1 -all).

Common breakages

Things that bite people after tightening the policy:

  • A department tool nobody told IT about. Found only when their emails vanish. This is why the monitoring phase matters.
  • Mailing lists that rewrite messages break DKIM. Modern list software rewrites the From header to avoid this; old setups don't.
  • Forwarding breaks SPF. Aligned DKIM usually saves you.
  • Sending "on behalf of" customers. If your app sends as user@theirdomain.com, their DMARC policy will reject it. Send from your domain and use Reply-To instead.
  • Typos in the record. A missing semicolon or p=rejct can make receivers ignore the record entirely. Always check after publishing.

Rollout checklist

  • [ ] p=none with rua reporting published
  • [ ] Reports collected for at least a few weeks, including monthly jobs
  • [ ] Every legitimate sending service listed
  • [ ] Each service passes aligned DKIM (and ideally aligned SPF)
  • [ ] SPF record under 10 lookups
  • [ ] p=quarantine ramped (for example 25 then 50 then 100), a week or more each
  • [ ] p=reject published, rua still on
  • [ ] sp= decided for subdomains; non-sending domains at p=reject

Check your record

Use the free DMARC checker to see what your domain publishes right now, and the DMARC generator to build the record for each stage. Authentication is only half of deliverability; the other half is sending to addresses that exist. MailRambo's API gives you 100 free checks a month for that, and the developer docs show how to add it to your stack.

Run these checks from your code

Verify addresses at signup, clean lists and read SPF/DKIM/DMARC with one API call. 100 free verifications a month, test keys that cost nothing, and the API on every plan.