Rolling out DMARC from p=none to p=reject without losing mail
The staged plan, what to look for in the reports at each stage, and the two mistakes that cause the horror stories people tell about DMARC.
DMARC has a reputation for breaking things. It deserves roughly half of it. The horror stories are real, and they almost all come from the same two mistakes: publishing an enforcing policy before knowing who sends as you, and treating the reports as noise rather than the whole point.
Done in stages, with the reports actually read, a rollout is uneventful. Here is the plan.
Before you start
You need two things:
- Somewhere to receive reports. A mailbox works. A DMARC reporting service works better — aggregate reports are gzipped XML, one file per receiver per day, and reading them by hand stops being fun around day three.
- A list of everything that sends mail as your domain. Write it down now, then be prepared to be wrong. The billing system, the recruiting tool, the monitoring alerts, the ten-year-old script on a server nobody owns — the reports exist to find the ones you forgot.
Stage 1: monitor (p=none)
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; fo=1
This changes nothing about how your mail is handled. Every receiver that supports DMARC starts sending you a daily summary of what it saw claiming to be from you: source IPs, volumes, and whether SPF and DKIM passed and aligned.
Stay here until: every legitimate source in your reports is passing DMARC — that is, passing SPF or DKIM with alignment to your From domain. Two to four weeks is typical, and longer if you have monthly systems (invoicing, payroll) that only appear once a billing cycle.
What you are looking for: the sources you do not recognise. Some will be forwarding, some will be a team that signed up for a SaaS tool with a company address, and some will be genuine spoofing. All three are useful findings.
Stage 2: fix what the reports found
For each legitimate sender that is failing:
- If it can DKIM-sign with your domain, do that. DKIM alignment survives forwarding; SPF alignment does not.
- If it can only do SPF, make sure its envelope domain aligns with your From domain — many ESPs offer a custom bounce or Return-Path domain for exactly this.
- If it is a system nobody owns any more, that is your answer: turn it off.
Keep an eye on the SPF lookup count while you are adding includes. Ten is a hard ceiling, and blowing past it fails SPF for everything, not just the new sender. The DNS checker counts them for you, including the ones your includes pull in behind them.
Stage 3: quarantine, partially (pct)
v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc@yourdomain.com; fo=1
pct=25 applies the policy to a quarter of failing mail and leaves the rest alone. If you missed something, you find out from a quarter of the blast radius.
Move 25 → 50 → 100 over a couple of weeks, watching the reports after each step. If a legitimate source appears in the failure column, go back to stage 2 rather than pressing on.
Stage 4: quarantine, fully
v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com; fo=1
Sit here for a couple of weeks. This is the stage that catches the low-volume monthly senders that the earlier stages statistically missed.
Stage 5: reject
v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc@yourdomain.com; fo=1
Failing mail is now refused at the SMTP transaction. This is the goal: it is the only policy that actually stops someone spoofing your domain at a receiver that honours DMARC.
Note sp=reject. Without an explicit subdomain policy, subdomains inherit p, which is usually what you want — but stating it removes the question. If you have a subdomain used by a system that cannot authenticate, give that subdomain its own record with a weaker policy rather than weakening the whole domain.
Keep rua= forever. Reports are how you find out that a newly onboarded vendor is failing, and there is no other signal that will tell you.
The two mistakes
Publishing p=reject on day one. It usually appears to work, because your main mail flow was probably fine. What breaks is the invoicing run three weeks later, the password-reset mail from an app nobody remembered, or the mailing list that rewrites nothing. By then the connection between "we published a DNS record last month" and "customers stopped receiving invoices" is hard to make.
Publishing DMARC with no rua=. This is enforcement with the lights off. You have told receivers to throw mail away and asked for no information about what is being thrown. Every stage above depends on the reports; without them a rollout is guesswork with consequences.
Two things DMARC does not do
- It does not stop display-name spoofing. "Support Team <attacker@gmail.com>" does not use your domain at all, so DMARC has no opinion about it.
- It does not stop lookalike domains.
yourc0mpany.comis somebody else's domain with its own perfectly valid DMARC record.
DMARC protects your domain, exactly. That is worth doing, and it is worth knowing what remains once you have.
Check your record
The DMARC fixer reads what you have published, validates every tag against the spec, tells you what each problem means, and generates the exact record for each stage above. It will also tell you when you are about to enforce a policy on a domain whose own mail is not yet authenticating — which is the moment the horror stories start.