1 June 2026 · DMARC Engine · 11 min read
DMARC enforcement is the point of the whole exercise. A policy of p=none tells the world's mailbox providers, "watch my domain, but do nothing about messages that fail." That is useful for a few weeks while you learn who sends mail as you. It protects nobody. Only p=quarantine and p=reject actually stop a forged email from landing in someone's inbox. The catch is the part that keeps people stuck at p=none for years: if you enforce before every legitimate sender passes authentication, you will quietly send your own invoices, password resets and newsletters to spam, or have them bounced outright. No error appears in your own mailbox. You find out when a customer complains.
This guide is the staged rollout that gets you to p=reject without that outage. It is deliberately unglamorous. You will inventory senders, fix SPF and DKIM until they align, publish p=none and actually read the reports, then ramp enforcement in controlled steps while watching the data. Done properly on a normal business domain, the whole journey takes six to twelve weeks. Rushed, it takes one bad afternoon and a week of cleanup.
Why p=none protects nothing
DMARC works by checking whether the domain in the visible From: header is backed by a passing, aligned SPF or DKIM result. "Aligned" is the word that trips people up. SPF can pass for the envelope sender (the Return-Path, also called MAIL FROM) while that domain is completely different from the From: domain your recipient sees. DKIM can pass for a signing domain that nobody recognises. DMARC only cares about the From: domain a human reads, and it requires at least one of SPF or DKIM to both pass and align with it.
Your published policy decides what a receiver does when neither aligns:
p=none: take no action, just send me reports. The message is delivered as if DMARC were not there.p=quarantine: treat failing mail as suspicious, usually route it to the spam or junk folder.p=reject: refuse the message at the SMTP layer, so it never arrives at all.
At p=none, a spoofed message claiming to be from your billing address sails straight through. The only thing you gain is visibility, and only if you collect the reports. That visibility is the entire reason none exists: it is a measurement phase, not a destination. Treat any domain still sitting at p=none after a couple of months as unfinished work.
Step 1: inventory every sender
You cannot authenticate senders you do not know about. The single biggest cause of broken email during a DMARC rollout is a forgotten service, the payroll platform, the event-booking tool, the CRM that sends on behalf of one department, the old marketing system somebody set up in 2019 and never decommissioned.
Build the list from three sources:
- What you already know. Walk the obvious ground: your mail platform (Google Workspace, Microsoft 365), your transactional email provider, your marketing platform, your help-desk, your CRM, your accounting and invoicing tools, any application servers that send directly.
- What the DNS already says. Read your current SPF record. Every
include:and every IP in it is a sender somebody once added. Run your domain through the SPF checker to see the expanded list and the lookup count. - What the reports reveal. This is the source you cannot fake. Once
p=noneis live and aggregate reports start arriving, every IP that ever sends as your domain shows up, including the ones you forgot and the ones spoofing you. You will almost always find a sender or two you did not list.
For each sender, record the From: domain or subdomain it uses, whether you can configure SPF and DKIM for it, and who owns the relationship internally. That last column matters more than it looks: half the delay in a rollout is waiting for someone in another team to log in to a console you do not control.
Step 2: fix SPF and the 10-lookup limit
SPF authorises which servers may send for your domain via the envelope sender. The rule that breaks SPF for growing organisations is in RFC 7208: evaluating a record must not require more than ten DNS lookups. Each include, a, mx, ptr and exists mechanism counts. Nested includes count too: if your provider's include pulls in three more includes, you have spent four of your ten on one entry.
Exceed ten and the result is permerror. A permerror is not a soft warning, it means SPF authentication fails, which under DMARC removes one of your two ways to pass. Mailbox providers treat the whole record as broken.
To find out where you stand, run your domain through the SPF checker; it expands every nested include and gives you the live lookup count. If you are over the limit, or close enough that adding one more vendor would tip you over, fix it like this:
- Remove senders you no longer use. The old marketing platform from the inventory step often costs you two or three lookups for nothing.
- Drop
ptrentirely. It is slow, unreliable and deprecated. If you seeptrin your record, delete it. - Flatten the record. Replace
include:mechanisms with the actual IP ranges they resolve to, so the lookups disappear. The trade-off is that flattened records go stale when a provider changes their infrastructure, so flattening needs monitoring to stay safe. Our SPF generator helps you build a clean record, and the hosted SPF service keeps a flattened record automatically updated when upstream ranges change so you never silently break.
End your record with -all (hardfail) once you are confident every legitimate IP is listed. Until then ~all (softfail) is the safer interim. Note one subtlety: SPF does not survive forwarding. When a mailing list or a forwarder relays your message, the sending IP changes and SPF breaks. This is exactly why you also need DKIM, and why DKIM is the more important of the two for reaching p=reject.
Step 3: get DKIM signing and aligning
DKIM attaches a cryptographic signature to the message, validated against a public key you publish in DNS. Because the signature travels with the message body and headers, it survives forwarding in a way SPF does not. For most domains, DKIM is what actually carries you through to enforcement.
Two things have to be true:
- Every sender signs. Each platform that sends as your domain needs DKIM enabled, which usually means generating a key in that platform's console and publishing the public half as a TXT or CNAME record at a selector you choose, for example
selector1._domainkey.yourdomain.com. Some providers manage this for you with a CNAME; others hand you a key to paste in. - The signature aligns. The DKIM signing domain (the
d=tag) must match yourFrom:domain, in relaxed alignment that means the same organisational domain. A provider that signs everything with its own domain gives you a passing DKIM that does not align, and DMARC ignores it. Check that your senders sign with your domain, not theirs.
Verify each selector with the DKIM checker. Use a 2048-bit key where the platform allows it; 1024-bit still validates but is weaker. The DKIM product page covers per-sender setup, and the broader DMARC product explains how alignment ties SPF, DKIM and DMARC together.
A useful mental model before you enforce: a message survives DMARC if either aligned SPF or aligned DKIM passes. You do not need both on every message. But you do want both configured wherever possible, because direct mail leans on SPF and forwarded mail leans on DKIM, and you want a passing result in as many real-world paths as you can.
Step 4: publish p=none and read the reports
Now publish your first DMARC record. Keep it minimal and, critically, include an aggregate report address so the data actually comes back to you:
v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.com; fo=1;
The rua tag is the aggregate report destination. Without it, p=none is blind and you learn nothing. The fo=1 tag asks for a failure report whenever any underlying check fails, which sharpens your diagnostics. Validate the syntax with the DMARC checker before you commit it.
Within twenty-four to seventy-two hours, the big providers start sending daily aggregate (RUA) reports: compressed XML summarising, per sending IP, how many messages claimed your domain and whether SPF and DKIM passed and aligned. Raw XML is unreadable at any volume. Paste it into the DMARC report analyzer to turn it into a sender-by-sender picture, or use continuous monitoring so reports are parsed automatically and you get alerted when something changes.
What you are looking for in these reports:
- Sources you recognise that now pass and align. Good. Tick them off the inventory.
- Sources you recognise that fail. These are your remaining work: a missing DKIM selector, a sender not in SPF, a platform signing with the wrong domain. Fix each before you tighten the policy.
- Sources you do not recognise. Either a forgotten legitimate sender (add it) or someone spoofing you (the exact threat enforcement will stop).
Do not skip ahead until your legitimate volume is reliably passing. The common figure people aim for is roughly 95 percent or more of legitimate mail passing aligned authentication before tightening the policy. Give yourself enough calendar time to catch low-frequency senders: the monthly invoice run, the quarterly report, the annual renewal notice. A two-week window will miss a sender that only fires once a month. Plan on three to four weeks at p=none for a typical domain, longer if your sending is seasonal.
Step 5: move to p=quarantine, ramping with pct
Once the reports are clean, step to p=quarantine. This is where the pct tag earns its keep. pct tells receivers what percentage of failing mail to apply the policy to; the rest falls back to the next-lower action. It lets you dip a toe in rather than enforce on everything at once.
Start low:
v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc-reports@yourdomain.com; fo=1;
At pct=25, only a quarter of failing messages get quarantined; the other three quarters are still delivered. If you have missed a sender, the blast radius is a quarter of its mail going to spam, not all of it, and the reports will show you immediately. Watch for a few days to a week, confirm nothing legitimate is being caught, then raise the percentage:
pct=25for several days, watch the aggregate reports.pct=50, watch again.pct=100, the full quarantine policy on all failing mail.
There is an important caveat about pct: support for it is uneven across receivers, and some treat partial percentages loosely. Treat the ramp as a confidence-building staircase and a way to limit damage, not as a precise dial. The real safety net is reading the reports at each step and being ready to roll back to the previous pct value, or to p=none, the moment a legitimate sender starts failing. DNS changes propagate in minutes when your TTL is sensible, so keep your DMARC record's TTL short, 300 to 3600 seconds, throughout the rollout so you can react fast.
Quarantine is a real improvement: forged mail now lands in spam rather than the inbox. But spam folders still get checked, and determined attacks still reach a fraction of users. Quarantine is a waypoint, not the finish.
Step 6: move to p=reject
When p=quarantine; pct=100 has run clean for one to two weeks, with no legitimate senders failing in the reports, promote to reject:
v=DMARC1; p=reject; rua=mailto:dmarc-reports@yourdomain.com; fo=1;
You can apply the same pct ramp here for extra caution (pct=25, then 50, then 100), though by this stage your data should already be solid. At p=reject, mail that fails DMARC is refused at the SMTP layer and never arrives. This is full protection: a forged message in your From: domain is bounced before it reaches anyone.
Keep the rua address in place permanently. Reaching p=reject is not the end of monitoring, it is the start of maintaining it. New senders get added over time, vendors change their sending infrastructure, and a flattened SPF record can drift. Continuous monitoring tells you when a previously-passing sender starts failing so you can fix it before anyone notices, and change alerts catch the day someone edits a DNS record they should not have touched.
Subdomain policy: do not forget sp=
Your DMARC policy applies to your organisational domain and, by default, to every subdomain that does not publish its own DMARC record. The sp= tag sets the policy for subdomains specifically, and it is the gap attackers love.
A common and dangerous mistake is to enforce on the root domain while subdomains stay open. If you publish p=reject but leave subdomains effectively unprotected, an attacker can forge accounts.yourdomain.com or secure-login.yourdomain.com, plausible-looking addresses that sail through because no policy covers them. Worse, many of those subdomains never send legitimate mail at all, so there is no reason to leave them open.
Two practical rules:
- For subdomains that never send mail, lock them down hard. Set
sp=rejecton the organisational record so any forged subdomain is rejected outright. - For subdomains that do send mail through their own platforms, give them their own staged rollout. Publish a DMARC record directly on the subdomain (for example a record at
_dmarc.mail.yourdomain.com) and walk it throughnone,quarantineandrejectexactly as you did the parent. While that subdomain is still learning, you can keepsplooser on the parent to avoid breaking it, then tighten once it is enforcing on its own.
If you omit sp=, subdomains inherit the p= value. That is fine once you are at p=reject across the board, but during the rollout an explicit sp= lets you treat parent and subdomains at different speeds, which you will usually need. A mature record for a domain whose subdomains do not send often looks like:
v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc-reports@yourdomain.com; fo=1;
A realistic timeline and what to monitor
For a typical business domain with a handful of senders, plan roughly:
- Week 0: inventory senders, fix SPF under the 10-lookup limit, enable DKIM on every platform.
- Weeks 1 to 4:
p=none, reading aggregate reports, chasing down failing and unknown senders until legitimate mail reliably passes. Watch: per-sender pass rates, unrecognised IPs, low-frequency senders you have not yet seen report in. - Weeks 5 to 6:
p=quarantine, rampingpctfrom 25 to 100. Watch: any sudden drop in a sender's pass rate, support tickets about missing mail, spam-folder placement. - Weeks 7 to 8:
p=reject, optionally ramped. Watch: bounce reports and aggregate data for any newly failing source, then settle into ongoing monitoring.
Domains with many senders, multiple business units or seasonal sending take longer, three months is normal and there is no prize for rushing. At every step the discipline is the same: change one thing, read the reports, confirm legitimate mail still passes, then take the next step. Keep TTLs short so a rollback is quick.
The practical takeaway
Reaching p=reject safely is not about cleverness, it is about sequence and patience: know your senders, make SPF and DKIM align, publish p=none and read the data, ramp through quarantine with pct, then reject, and lock down subdomains with sp= so the back door is shut. The one rule that prevents outages is never tightening the policy until the reports prove your legitimate mail already passes.
If you would rather not parse XML by hand, run your domain through the free DMARC checker and SPF checker to see where you stand today, or browse the full toolset. And if you want the staged rollout driven for you, with SPF kept under the lookup limit, DKIM aligned across every sender, and reports turned into plain-English monitoring with alerts, that is precisely what the done-for-you DMARC service handles, taking you from p=none to p=reject with no email outage. The requirements page covers what regulators and the big mailbox providers now expect, in case you need a deadline to point at.