Rolling Out A DMARC Policy Without Breaking Mail
The Mythic Intel Team · Sep 19, 2025 · 7 min read
Rolling out DMARC without breaking legitimate mail means moving through three policy states in order, starting at p=none to observe, advancing to p=quarantine to soft-enforce, and finishing at p=reject to hard-enforce, with aggregate reports driving every step. The mistake that breaks mail is jumping straight to p=reject before you have confirmed that every legitimate sender, including the ones you forgot about, passes alignment. DMARC tells receivers to drop or quarantine mail that fails, so an early enforcement policy will silently bin your own newsletters, billing notices, and SaaS-relayed mail.
DMARC sits on top of SPF and DKIM and adds two things they lack: alignment and reporting. Alignment requires that the domain validated by SPF or DKIM matches the domain in the visible From header, which is what stops an attacker from passing SPF on some unrelated domain while spoofing yours. Reporting gives you a daily feed of who is sending as your domain so you can find and fix every legitimate source before you turn on enforcement.
The staged rollout
The whole point of staging is to enforce only after the reports show you a clean picture.
Stage one, observe. Publish a monitoring record and collect aggregate reports for two to four weeks. Nothing is enforced; you are building an inventory of senders.
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; adkim=r; aspf=r; fo=1"
Read the tags:
v=DMARC1is mandatory and must come first.p=noneis the policy: take no action, just report.rua=is where aggregate (statistical) reports go. These are the reports you actually act on.ruf=is where per-message failure reports go. They contain message detail and are sent by far fewer receivers for privacy reasons.adkimandaspfset DKIM and SPF alignment to relaxed (r) or strict (s). Relaxed lets a subdomain align with the organizational domain; strict requires an exact match. Start relaxed.fo=1asks for a failure report whenever any underlying mechanism fails alignment, which is more useful than the default during rollout.
Stage two, soft-enforce. Once the reports show your real senders passing SPF or DKIM in alignment, move to quarantine. Quarantined mail is delivered to spam rather than the inbox, so a missed sender degrades but does not vanish.
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]; adkim=r; aspf=r"
Stage three, hard-enforce. When quarantine has run clean, move to reject. Failing mail is refused at SMTP time.
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:[email protected]; adkim=r; aspf=r"
Ramping enforcement gradually with pct, and what changed
The classic way to ease into enforcement under RFC 7489 is the pct tag, which applies the policy to only a fraction of failing messages. p=quarantine; pct=25 quarantines a quarter of failing mail and treats the rest as none, so you can watch the report deltas before going to 100 percent.
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=25; rua=mailto:[email protected]"
In practice receivers only ever implemented pct=0 and pct=100 reliably, and the values in between were inconsistent. The DMARC revision published as RFC 9989 in May 2026 deprecated pct entirely (along with ruf) and replaced gradual rollout with a t=y test-mode flag, which asks receivers to apply the next-lower policy while you validate at a given level. If you are writing new records, prefer the test flag; if you are reading existing records, you will still see pct in the wild for years.
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; t=y; rua=mailto:[email protected]"
That record asks for reject semantics but tells receivers to behave as quarantine while you watch, which is the modern equivalent of p=reject; pct=0.
Reading the reports
Aggregate reports are gzipped XML, sent daily, one per receiver. Each row tells you a source IP, a count, the From domain, and whether SPF and DKIM passed and aligned. The pattern you are hunting for before enforcement:
<record>
<row>
<source_ip>198.51.100.7</source_ip>
<count>148</count>
<policy_evaluated><disposition>none</disposition>
<dkim>pass</dkim><spf>fail</spf></policy_evaluated>
</row>
<identifiers><header_from>example.com</header_from></identifiers>
</record>
This source passes DKIM in alignment, so it survives DMARC even though SPF fails (a forwarded or relayed path). A source where both DKIM and SPF show fail and you do not recognize the IP is either a forgotten legitimate sender to fix or a spoofer you are about to block. You advance a stage only when every IP with real volume shows at least one aligned pass.
The current bulk-sender requirements
Since February 2024, Google and Yahoo require bulk senders, defined as domains sending roughly 5,000 or more messages a day to their users, to publish a DMARC policy on the From domain (a policy of p=none satisfies the minimum), to authenticate with both SPF and DKIM in alignment, to support one-click unsubscribe via the List-Unsubscribe and List-Unsubscribe-Post headers, and to keep the spam complaint rate below 0.3 percent. Google's own guidance is to stay under 0.1 percent and treat 0.3 percent as the line you must not cross. DMARC is the requirement that forces the staged rollout above onto every commercial sender, because you cannot meet the mandate without a published policy and you cannot publish enforcement safely without first reading the reports.
Saying it out loud
In an interview, frame it as risk management: "DMARC adds alignment and reporting on top of SPF and DKIM. I roll it out in three stages, none to inventory senders from the aggregate reports, quarantine to soft-enforce, reject to hard-enforce, and I only advance when every legitimate source shows an aligned pass. I would use t=y rather than pct on new records since the 2026 revision deprecated pct. And the reason every bulk sender now has to do this is the 2024 Google and Yahoo mandate: a published DMARC policy plus aligned SPF and DKIM plus one-click unsubscribe plus a complaint rate under 0.3 percent." That answer shows you treat enforcement as a reporting-driven process, not a config you flip on day one.