CrawlCheck

Guides · 2026-09-30 · By · 2 views

DMARC p=none to p=quarantine without losing mail: a guide

The sequence for tightening DMARC safely: inventory every sender, prove alignment from received headers, create the report mailbox first, then raise the policy in stages.

DMARC passes when SPF or DKIM passes on a domain aligned with the visible From address. To move from p=none to p=quarantine without losing mail: list every system that sends as your domain, read the Authentication-Results header on a real message from each, get DKIM aligned on all of them (SPF alone fails on forwarding), create the rua report mailbox before the record names it, then publish quarantine at pct=25 and raise it as the aggregate reports stay clean. Set sp= deliberately.

A DMARC record with p=none is a monitoring instruction: it asks receiving mail servers to report what they see and to deliver everything anyway. Most domains that have a record stop there, because the next step, p=quarantine, is the one that can send your own legitimate mail to spam if anything is misconfigured. This guide is the sequence for making that move safely, written from doing it on crawlcheck.io in September 2026, where two separate sending systems both had to pass before the policy could tighten, and updated for the DMARC revision published as RFC 9989 in May 2026.

Key points
  • DMARC passes when SPF or DKIM passes on a domain aligned with the visible From address.
  • Inventory every sender, then prove each one from the Authentication-Results header of a real delivered message.
  • Get DKIM aligned on every sender: SPF fails whenever mail is forwarded, and aligned DKIM survives it.
  • Create the rua= report mailbox before the record names it.
  • RFC 9989 (May 2026) removes pct and adds a t=y testing flag that applies the next less strict policy; it is not an off switch.

What does DMARC actually evaluate? #

How DMARC decides: pass and alignTHE MESSAGEThree domainsFrom: you@example.comenvelope: bounce.example.comDKIM d=example.comSPFpassed? aligned withthe From domain?DKIMpassed? d= aligned withthe From domain?DMARC passeither one passesand alignsRelaxed alignment (the default) accepts any domain under the same organisational domain.A sender that passes SPF or DKIM on its own domain, not yours, passes nothing that DMARC counts.
DMARC adds no new authentication. It asks whether SPF or DKIM passed for a domain that matches the visible From address.

DMARC does not authenticate anything itself. It reads the results SPF and DKIM already produced and asks about alignment. Did SPF pass, and is the domain SPF checked (the envelope sender) the same organisational domain as the visible From address? Did DKIM pass, and is the d= domain in the signature the same organisational domain as the From address? If either pair passes and aligns, DMARC passes. If neither does, the policy applies: none delivers, quarantine asks the receiver to treat the message as suspicious, reject asks it to refuse. The most common cause of legitimate mail failing under quarantine is a sender that passes on a domain that does not align: a marketing platform that signs with its own domain, or a form tool that uses its own envelope sender.

Step one: inventory every sender #

Before touching the policy, list every system that sends mail with your domain in the From address. Mailboxes are the obvious one. The rest hide: a transactional sender inside your web application, a form tool, a CRM, a support desk, a newsletter platform, a monitoring service that emails alerts, a billing provider. On crawlcheck.io there were two: the Google Workspace mailboxes, and the site’s own application, which sends scan alerts and other notifications. They use different SPF includes and different DKIM selectors, and both had to align independently.

Step two: prove each one passes, from a received message #

The reliable proof is not the DNS record; it is the Authentication-Results header on a message each sender actually delivered. Send one message from each system to a mailbox you control, open the raw source, and read the line (shortened here):

Authentication-Results: mx.google.com;
  dkim=pass header.i=@crawlcheck.io header.s=cf-bounce header.b=…;
  spf=pass (google.com: domain of …@cf-bounce.crawlcheck.io designates … as permitted sender);
  dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=crawlcheck.io

For the application mail, DKIM passed on crawlcheck.io and SPF passed on the cf-bounce subdomain, which aligns at the organisational level. For the Workspace mailboxes the same line first showed SPF passing and no DKIM at all, because the Workspace DKIM key had never been generated. That is a pass today and a single point of failure.

SenderSPFDKIMAlignedUnder quarantine
Workspace mailbox, before DKIMpass (include:_spf.google.com)noneSPF onlypasses, fails if forwarded
Workspace mailbox, after DKIMpasspass, s=google, d=crawlcheck.iobothpasses
Application mail (cf-bounce)pass on cf-bounce subdomainpass, s=cf-bounce, d=crawlcheck.iobothpasses
a form tool signing its own domainpass on its domainpass, d=formtool.exampleneitherquarantined

Why is SPF alone not enough? #

Why forwarding breaks SPF but not DKIMYour serversends from itslisted IPForwarderre-sends fromits own IPSPF: failthe forwarder’s IP is not in your SPF recordDKIM: passthe signature covers the content, which did not changeWith aligned DKIM the message still passes DMARC. With SPF alone it fails.
Mailing lists, alias services and forwarding rules all re-send mail from their own servers. Aligned DKIM is what keeps that mail passing once the policy tightens.

A forwarding server re-sends the message from its own address, which is not in your SPF record, so SPF fails at the final receiver. The DKIM signature is computed over the headers and body, which forwarding normally leaves alone, so it still verifies. That is why the safe precondition for quarantine is aligned DKIM on every sender, not SPF on every sender.

Step three: give the reports somewhere to land #

Where the evidence comes fromReceiversGmail, Outlook,Yahoo and othersrua= mailboxone XML report perreceiver per dayWhat you learnevery source IP thatsent as your domainThe trapthe mailbox must exist before the record names it, or every report bounces
Aggregate reports are the only view of senders you forgot to list. They are worth nothing if the address in rua= does not receive mail.

The record names a rua= address for aggregate reports. Receivers send one XML report per day per receiver naming every source IP that sent as your domain and how each fared; this is the only view you have of senders you forgot in step one. On crawlcheck.io the record pointed reports at dmarc@crawlcheck.io before that alias existed, so the reports bounced for the whole period they were most needed. Create the mailbox or alias first, send a test to it, and only then publish the record that names it.

How do you read an aggregate report? #

Each report is a small XML file. The part that matters is one record per sending source:

<record>
  <row>
    <source_ip>203.0.113.7</source_ip><count>42</count>
    <policy_evaluated><disposition>none</disposition>
      <dkim>fail</dkim><spf>pass</spf></policy_evaluated>
  </row>
  <identifiers><header_from>example.com</header_from></identifiers>
</record>

Read it as: 42 messages claiming to be from your domain came from 203.0.113.7; DKIM did not align, SPF did, so DMARC passed on SPF alone. Look up who owns the address. If it is a system you use, it is a sender to fix before tightening, because the first forwarded message from it will fail. If you do not recognise it at all, it is either a sender nobody told you about or someone forging your domain, and the report is how you find out which. Reports are compressed and arrive per receiver, so a parser or a reporting service saves time once volume grows; reading a few by hand first teaches you what the numbers mean.

Step four: how do you raise the policy in stages? #

Tightening DMARC one step at a time under RFC 9989p=nonemonitordeliver all, reportp=quarantine; t=yapplied as nonesignals intentp=quarantinespam folderfor failing mailp=reject; t=yapplied asquarantinep=rejectrefusedat the doorRead a week of aggregate reports at each step; move up only when no source you recognise is failing.
Under RFC 9989 (May 2026) the t=y testing flag replaces pct: it applies the next less strict policy, so p=reject; t=y is enforced as quarantine. It is not an off switch.

The original specification staged enforcement with pct=, applying the policy to a percentage of failing messages. RFC 9989, which replaced RFC 7489 in May 2026, removes pct because receivers applied it inconsistently, and adds a testing flag. With t=y, receivers apply the next less strict policy: p=reject; t=y is enforced as quarantine, and p=quarantine; t=y as none. Receivers may still honour pct during the transition, but new records should use the new tag. Note what t=y is not: it is not the old pct=0 off switch, and treating it as one loosens a domain by a full level.

RecordWhat failing mail getsUse it when
p=nonedelivered; reportedyou are still listing senders
p=quarantine; t=ydelivered (applied as none)you want intermediaries to see the intended policy before enforcing it
p=quarantinespam folderevery known sender aligns DKIM and the reports are clean
p=reject; t=yspam folder (applied as quarantine)quarantine has run clean and you are preparing for reject
p=rejectrefusedreports show no legitimate source failing over a full business cycle

Two more tags deserve a deliberate decision. sp= sets the policy for subdomains; left unset they inherit p, and a subdomain that sends through some other system will start failing when the parent tightens. RFC 9989 also adds np=, the policy for subdomains that do not exist at all, which is the tightest anti-spoofing control in the record because no legitimate mail can come from a name that does not exist. The record crawlcheck.io publishes today reads:

v=DMARC1; p=quarantine; sp=quarantine; pct=100; adkim=r; aspf=r; rua=mailto:dmarc@crawlcheck.io; fo=1

pct=100 applies the policy to everything and is harmless under either specification; on the next edit it can simply be removed.

What will quarantine not fix? #

DMARC governs the visible From domain only. A phishing message that uses a lookalike domain, or your brand name in the display name over a different address, passes DMARC because it is not claiming your domain. What tightening does is remove exact-domain forgery, the kind that most reliably defeats a reader, and remove your domain from the pool of spoofable senders. The neighbouring pieces, an MTA-STS policy to stop transport downgrade and a TLS-RPT address to hear about it, are described on the trust center; the single-character bounce that started this work is in its own post.

Checklist #

  1. List every system that sends as your domain.
  2. Read Authentication-Results on a real message from each, and get DKIM aligned on all of them, not just SPF.
  3. Create the report mailbox and confirm it receives.
  4. Publish p=quarantine (optionally with t=y first), read the reports, then tighten.
  5. Set sp= and np= deliberately.

A scan on crawlcheck.io reads the SPF and DMARC records as published and reports what policy is in force; it cannot see your senders, which is why step two is done by hand.

Every figure above came out of this scanner.

Point it at your own domain and see the same measurements, free.

Scan a domain — free

The main product

Found this on your own site? We fix it for $749.

Scan free to see where you stand. The fix is one site, every finding implemented and re-measured, with a sealed before and after.

Questions this post answers

What does p=none do?

It asks receivers to deliver everything and send reports. It is a monitoring setting, not a protection; forged mail using the exact domain is delivered normally under p=none.

What is DMARC alignment?

The domain that passed SPF or DKIM must match the organisational domain in the visible From address. A sender can pass SPF or DKIM on its own domain and still fail DMARC because nothing aligned.

Why does SPF alone fail when mail is forwarded?

A forwarding server re-sends the message from its own IP, which is not in your SPF record, so SPF fails at the final receiver. A DKIM signature survives forwarding because it is computed over the message content, which is why aligned DKIM is what makes quarantine safe.

Is the DMARC pct tag still valid?

RFC 9989, published in May 2026, removes pct and replaces its testing use with the t= tag. Receivers may still honour pct during the transition, but new records should use t=y for testing.

What does t=y do in a DMARC record?

Under RFC 9989 it applies the next less strict policy: p=reject with t=y is enforced as quarantine, and p=quarantine with t=y as none. It is not an off switch like the old pct=0.

Where do DMARC aggregate reports go?

To the address in the record's rua tag, one XML report per receiver per day. The address must exist before the record names it; reports sent to a non-existent mailbox bounce and are lost.

Should I go straight to p=reject?

Only after quarantine has run long enough for the reports to show no legitimate source failing. Reject refuses the message outright, so a sender you forgot loses mail instead of having it filtered.

What is the np= tag?

Added by RFC 9989, np= sets the policy for subdomains that do not exist. Since no legitimate mail can come from a name that does not exist, it can usually be set to reject safely.

How long does a DMARC change take to work?

Receivers read the new record when their cached copy expires, which is set by the TXT record's TTL. Lower the TTL a day before the change if you want it to apply quickly. Aggregate reports usually arrive once a day, so allow at least 48 hours before judging the effect.

How long should I stay at p=quarantine before p=reject?

Until the reports show every legitimate sender passing for a full cycle of your mail, including monthly senders such as invoices and newsletters. For most domains that is several weeks. Move when the only failures left are messages you did not send.

Related findings

How anything measured in this article was measured15client identitiesone second, one address5machine filesapex and www114named agentsresolved from robots.txt24sections scoredreach, read, quoteHow anything measured here was measured15 client identities5 machine files114 named agents24 sections scoredone second, one addressapex and wwwresolved from robots.txtreach, read, quote
No account, nothing installed, and the same sequence on every domain — which is what makes one scan comparable to another. Run it on your own site.

Comments

Comments are read before they appear. Nothing is published automatically, and no account is needed.

Writing about this? Facts, live figures and marks — every number on that page is dated and traceable to a scan.

All guides · The dataset · How the dataset works