Reaching p=reject without losing a single legitimate email

The method we use to take a domain from p=none to p=reject: in what order, at what pace, and the three mistakes that send everyone back to square one.

Everyone knows a DMARC policy should end up at p=reject. Almost nobody gets there. The reason is simple, and it is not technical: the day you flip the switch, if you got it wrong, your ERP invoices stop reaching your customers — and nobody tells you. The mail does not bounce with a helpful message. It disappears.

That risk is real. It is also entirely avoidable, as long as you stop treating this as "publishing a DNS record" and start treating it as a migration.

Why p=none protects nothing

Worth restating, because the confusion is common. A p=none policy tells receiving servers: "report to me what you see in my name, but change nothing." It is observation mode. An attacker spoofing your domain while you sit at p=none will have their messages delivered normally — you simply get the report a few hours later.

p=quarantine asks receivers to treat failures as suspicious; p=reject asks them to refuse. Only the last one actually shuts the door.

What actually breaks, and why

In the migrations we run, legitimate mail that fails DMARC almost always falls into one of these buckets.

Third-party services sending in your name. Billing tool, recruitment platform, e-signature service, marketing mail router, ticketing system. Each was wired up one day by a different team, and nobody keeps the list. By a wide margin, this is the leading cause of failure.

Missing alignment. A message can pass SPF and still fail DMARC: DMARC requires the domain validated by SPF to match the one shown in the From: header. Many platforms send with their own envelope domain, which passes SPF technically without aligning you.

Forwarding. An address that forwards mail to another mailbox breaks SPF by construction — the relaying server is not in your record. DKIM survives forwarding, unless something in the middle modifies the message.

Mailing lists. Same mechanics, made worse by lists that rewrite the subject or append a footer: the DKIM signature dies with it.

The method, in order

1. Publish in observation mode, and actually wait

Publish p=none with an aggregate reporting address, and let it run. Two weeks is rarely enough: you need to cover at least one billing cycle, one marketing campaign, one payroll run. We plan for four to six weeks on a primary domain.

The goal of this phase is not to collect reports. It is to build the complete inventory of what sends in your name — including what you did not know about.

2. Sort the inventory into three piles

Every identified source goes into one of three:

PileDecisionTypical example
Legitimate, align itConfigure SPF and DKIM at the providerERP, HR tool, marketing
Legitimate, retire itCut the source, migrate the use caseOld print server, forgotten script
IllegitimateDo nothing — this is what p=reject will blockPhishing, spoofing

That third pile is what justifies the whole exercise. On a reasonably well-known mid-market domain, it routinely runs to several thousand messages a month.

3. Align, without touching the policy

At each legitimate provider: enable DKIM signing with your own domain, and check that the envelope domain aligns. This is configuration work, provider by provider, and it is the longest part. It carries no risk: while the policy stays at p=none, nothing can be rejected.

Prefer DKIM over SPF wherever you can. DKIM survives forwarding, consumes no DNS lookup, and does not depend on the provider's IP addresses — which will change without warning you.

4. Move in stages, using a percentage

DMARC accepts a pct tag that applies the policy to only a fraction of traffic. That is your safety net:

v=DMARC1; p=quarantine; pct=25; rua=mailto:...

Our reference progression, one step a week, checking the reports in between:

  1. p=quarantine; pct=25
  2. p=quarantine; pct=100
  3. p=reject; pct=25
  4. p=reject; pct=100

An incident at 25% shows up in the reports and gets fixed before it touches the other three quarters. That is the entire point.

5. Do not stop there

A domain at p=reject is not a solved domain. An acquisition, a new SaaS tool, a provider changing infrastructure: each of these can reintroduce an unaligned source. Without monitoring, you will find out the day a customer tells you they never received anything.

How long it really takes

On a primary domain with a dozen legitimate sources, expect six to ten weeks from the first record to p=reject; pct=100. Most of that time is deliberate waiting, not workload.

Across a fifty-domain estate — the reality for any group that acquires regularly — the work is not fifty times longer: most secondary domains send nothing at all and can go straight to p=reject with an empty SPF record. Those are in fact the urgent ones: a domain that never sends mail is the easiest spoofing target there is, because nobody is watching what leaves it.

David PekmezTwenty years securing Microsoft environments and corporate email, from the endpoint to tenants with several thousand accounts. LinkedIn
Share on LinkedIn

And where does your configuration stand?

Thirty minutes to look at your actual situation. If this article applies to you, we will tell you frankly how much.