Guides
Getting to DMARC p=reject without breaking your mail
19 July 2026 · 3 min read · TMailr
p=reject is the goal and it is also the setting that makes your invoices disappear. The difficulty is never the record itself, which takes a minute to publish. It is that you almost certainly send mail from more places than you can list from memory.
Start by watching
Publish p=none with a reporting address. Nothing changes for any receiver, and within a day you start getting daily XML summaries naming every source sending as your domain and whether each aligned.
v=DMARC1; p=none; rua=mailto:dmarc@example.com
This is the only step that cannot be skipped. The list of senders it produces is always longer than expected, and the surprises are the point: the payroll system, the ticketing tool somebody set up in 2019, the CRM sending from a subdomain nobody documented, the office printer.
Read the reports for long enough
Two weeks catches the daily and weekly senders. A month catches the monthly invoice run. A quarter catches the annual thing that will otherwise fail in a way nobody connects to a DNS change made months earlier.
You are looking for sources that are yours and do not align. Each needs fixing before enforcement, and the fix is nearly always to have that sender sign with DKIM using a key on a subdomain you control, rather than trying to add its IP addresses to your SPF record.
Why DKIM rather than SPF
SPF is limited to ten DNS lookups and each supplier you add can consume several. Records drift over the limit slowly, and going over is a permanent error rather than a soft failure, which many receivers treat as no SPF at all. DKIM has no equivalent ceiling and it survives forwarding, which SPF cannot. If you can only fix one leg, fix DKIM.
Move in steps you can undo
- p=none until the reports are boring.
- p=quarantine with t=y, the testing mode. A compliant receiver treats a testing policy one level softer than it reads, so this behaves like p=none: you get the quarantine-level reporting while no real mail is quarantined yet.
- p=quarantine on its own once that step is clean. Now failing mail actually goes to spam.
- p=reject with t=y, the last dry run. Testing mode drops it one level, so it behaves like quarantine while you watch for anything that should not be refused.
- p=reject.
Give each step a week or two. The testing tag is what makes a step undoable: a mistake shows up in the reports at the stricter level before that level actually bites, so you find out before the whole flow is at risk.
Two things people forget
The subdomain policy. Without sp=, subdomains inherit the main policy, which is usually what you want. If you have a subdomain that legitimately sends unaligned mail, set sp= explicitly rather than weakening the parent.
And the reporting address itself. If rua points at a different domain, that domain has to publish an authorisation record before anybody will send it anything. Without it the reports are dropped silently, and it looks like nobody is sending as you at all, which is the most dangerous possible misreading right before you turn on reject.
More on guides