Start at p=none, read the aggregate reports until every legitimate sender passes DMARC with an aligned SPF or DKIM identifier, then move to p=quarantine, and later to p=reject. Do not skip the reading: reject tells receivers to refuse mail that fails, including your own invoices if a sender was forgotten. Under the current standard, RFC 9989 (DMARCbis, May 2026), the old pct tag for partial rollout is gone; the test flag t=y takes its place. Check where you stand with the DMARC checker.
What each policy asks receivers to do
| Policy | Request to receivers | Risk if a sender is unaligned |
|---|---|---|
p=none | Monitoring only; take no action because of DMARC | None to delivery; reports are generated |
p=quarantine | Treat failing mail with suspicion, typically spam folder | Legitimate mail lands in spam |
p=reject | Reject failing mail during SMTP | Legitimate mail bounces |
These are requests. RFC 9989 §5.4 says receivers may still accept failing mail under reject, and should not reject solely because of the published policy. Do not assume enforcement is uniform.
Step 1: collect reports at p=none
Publish a record with a rua address and wait. RFC 9989 §5.1.5 notes that starting at p=none “takes advantage of DMARC’s aggregate reporting function.”
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
Give it two to four weeks so monthly senders (billing, payroll, newsletters) appear. How to read the XML or a report service is covered in DMARC reports explained.
Step 2: fix what fails
For every source IP that sends as your domain, one of the two must pass with alignment: SPF with the envelope sender in your domain, or DKIM signing with a d= in your domain. RFC 9989 §5.1.6 says shortcomings must be addressed before publishing an enforcement policy. Typical fixes are enabling custom DKIM at a third-party sender and aligning the return-path. The cause of a specific failure is in DMARC fails although SPF and DKIM pass. Header-level evidence for one message is shown by the email header analyzer.
Mail you cannot fix should be stopped by the policy: unknown IPs with no business reason are the point of the exercise. Mail from forwarders and mailing lists often fails SPF and may break DKIM; accept some residual failures and decide per source.
Step 3: ramp up to enforcement
Old way: pct
Under RFC 7489, pct=10 asked receivers to apply the policy to roughly 10% of failing mail, and the rest fell back to the next lower policy. Domain owners raised the value in steps: p=quarantine; pct=10, then 25, 50, 100, then p=reject; pct=10 and so on.
Current way: t=y
RFC 9989 removes pct (Appendix A.6). Its stated reason: “operational experience showed that the ‘pct’ tag was usually not accurately applied,” except at 0 or 100. It adds t, “DMARC policy test mode”, with y or n (default n), described as analogous to the old pct=0 and pct=100. With t=y, the receiver does not apply the stated policy and instead applies one level lower: reject acts as quarantine, and quarantine acts as none (§4.7). Reports are still produced.
# step A: quarantine in test mode (receivers act as for none)
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=quarantine; t=y; rua=mailto:dmarc@example.com"
# step B: quarantine for real
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"
# step C: reject in test mode (receivers act as for quarantine)
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=reject; t=y; rua=mailto:dmarc@example.com"
# step D: reject
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
Trade-off: t=y is a two-state switch, not a dial. You cannot get “10% of failing mail” any more. And because DMARCbis adoption is uneven, receivers still following RFC 7489 may ignore t and apply the full policy, and may still honour pct. If you keep a pct value for those receivers, the checker warns that DMARCbis receivers ignore it. Run at each step for at least a reporting cycle and compare the failing volume before moving on.
sp and np
sp sets the policy for existing subdomains; np sets it for non-existent subdomains. If np is absent, sp applies, and if that is absent too, p (RFC 9989 §4.7). Non-existent subdomains send no legitimate mail, so np=reject is usually safe even while p=none:
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=none; np=reject; rua=mailto:dmarc@example.com"
The checker notes that np stricter than p=none applies only to subdomains that do not exist. A subdomain that sends its own mail needs its own review, or its own record at _dmarc.sub.example.com. If a record exists there it takes precedence over the parent’s sp. Never put sp=reject on a domain that has live subdomains you have not seen in reports.
Rolling back
Lower the TTL (for example 300) before each step so you can revert fast. If bounces start, set p back and read the failing sources in the next report. See DMARC syntax errors if the new record does not take effect, and How to set up a DMARC record for the first record.
FAQ
How long should I stay at p=none? Until reports show no legitimate source failing, usually two to four weeks at least. There is no fixed number in the RFC.
Is p=quarantine required before reject? No, but it gives a softer failure mode: spam-foldered mail is recoverable, bounced mail is not.
Should I delete pct from an existing record?
Yes, when you edit the record. RFC 9989 removed it, and the checker only warns about it. Use t=y for testing instead.
Sources
- RFC 9989, DMARC (obsoletes RFC 7489), §4.7 Policy Record Format (p, sp, np, t): https://www.rfc-editor.org/rfc/rfc9989.html#section-4.7
- RFC 9989, §5.1.5 to §5.1.7 Domain Owner Actions: https://www.rfc-editor.org/rfc/rfc9989.html#section-5.1
- RFC 9989, §5.4 Policy Enforcement Considerations: https://www.rfc-editor.org/rfc/rfc9989.html#section-5.4
- RFC 9989, Appendix A.6 Removal of the “pct” Tag: https://www.rfc-editor.org/rfc/rfc9989.html#appendix-A.6
- RFC 7489 (legacy), §6.3 pct tag: https://www.rfc-editor.org/rfc/rfc7489#section-6.3