DMARC Deployment in Depth
Operational DMARC deployment — full tag reference, subdomain policy, pct sampling, alignment strictness, report processing, forwarding/mailing-list failure modes, and the none→quarantine→reject rollout.
Operational8 min read
Who it is for ESP operators, Senders
Applies to senders on any platform
ContentsOn this page — 9 sections
Once you understand what DMARC does, moving a domain to enforcement safely means getting many details right: the full set of tags, subdomain policy, percentage sampling, alignment strictness, report handling, the common failure scenarios, and the order of the rollout. For the concepts, alignment and the basic record, start with DMARC.
The material below is drawn from dmarc.org, the home of the DMARC specification.
Specification status
| Document | Role | Status |
|---|---|---|
| RFC 7489 (March 2015) | Original DMARC specification (Informational) | Obsoleted |
| RFC 9989 (May 2026) | Core DMARC protocol ("DMARCbis", Standards Track) | Current |
| RFC 9990 (May 2026) | Aggregate reporting | Current |
| RFC 9991 (May 2026) | Failure reporting | Current |
The main changes in the new RFCs do not break existing records, which still begin with v=DMARC1:
- Removed tags:
pct,rfandri.pctwas removed because its definition in RFC 7489 was ambiguous from the start ("percentage of messages from the Domain Owner's mail stream to which the DMARC policy is to be applied"). - New tags:
np(policy for non-existent subdomains),psd(a flag for public suffix domains), andt(a testing flag, which replaces thepct=0-style use of "monitor but don't enforce"). - Discovery of the Organizational Domain: the Public Suffix List is replaced by a DNS Tree Walk. The receiver queries
_dmarc.<author-domain>, then_dmarc.<parent>, and so on up the tree, up to a limit of eight queries.
Most deployed records and receivers still use the semantics of RFC 7489, so the tag reference below covers both.
Full tag reference
DMARC records use the extensible tag-value syntax taken from DKIM. All tags other than v and p are optional.
| Tag | Purpose | Example | Notes |
|---|---|---|---|
v |
Protocol version. Must be first | v=DMARC1 |
Only valid value |
p |
Policy for the Organizational Domain | p=quarantine |
none, quarantine or reject |
sp |
Policy for subdomains of the Organizational Domain | sp=reject |
Defaults to the p value when absent |
pct |
Percentage of failing messages to which the p policy is applied |
pct=20 |
RFC 7489 only. Removed in RFC 9989 |
rua |
One or more URIs for aggregate reports | rua=mailto:aggrep@example.com |
Separate multiple URIs with commas |
ruf |
One or more URIs for failure ("forensic") reports on individual messages | ruf=mailto:authfail@example.com |
|
adkim |
DKIM alignment mode | adkim=s |
r (relaxed, default) or s (strict) |
aspf |
SPF alignment mode | aspf=r |
r (relaxed, default) or s (strict) |
fo |
Failure-report options | fo=1 |
0 both fail (default), 1 either fails, d DKIM fail, s SPF fail |
rf |
Failure report format | rf=afrf |
RFC 7489 only. Removed in RFC 9989 |
ri |
Requested interval between aggregate reports (seconds) | ri=86400 |
RFC 7489 only. Removed in RFC 9989 |
np |
Policy for non-existent subdomains | np=reject |
New in RFC 9989 |
psd |
Marks a record published at a public suffix domain | psd=y |
New in RFC 9989 |
t |
Testing flag: evaluate but do not enforce | t=y |
New in RFC 9989. Replaces the sampling role of pct |
Example record:
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; pct=100; rua=mailto:postmaster@example.com"
Subdomain policy (sp=)
Without sp=, subdomains inherit the p= policy of the Organizational Domain. Publishing sp= lets you enforce differently in different parts of the organization, for example:
p=none; sp=reject: the apex domain is still being monitored, while spoofed mail on subdomains that send no mail is rejected.p=reject; sp=none: the apex is locked down while the mail streams of a subdomain are still being brought into alignment. Attackers can exploit this weak spot, so close it as soon as possible.
To be eligible for BIMI, both must be at enforcement: p=quarantine|reject, with no sp=none (see BIMI). RFC 9989 also adds np=, so that non-existent subdomains can be rejected even while real subdomains have a looser policy.
Percentage sampling (pct=, RFC 7489)
pct sets the percentage of failing messages to which the p= policy is applied. The remaining messages receive the next lower policy:
p=reject; pct=60means that 60% of failing traffic is rejected and 40% is quarantined.p=quarantine; pct=25means that 25% is quarantined and 75% is treated asnone.
This built-in control allows gradual enforcement: raise pct in steps at each policy level, and watch the reports before going to 100. Under RFC 9989, pct no longer exists. The t=y testing flag covers the case of publishing an intention to enforce without any effect, and a gradual rollout moves from one policy level to the next.
Alignment strictness (adkim= / aspf=)
Both alignment tags accept:
r(relaxed, default): the authenticated domain (DKIMd=or the SPF RFC5321.MailFrom) only needs to share the Organizational Domain with the RFC5322.From domain.news.example.comaligns withexample.com.s(strict): the domains must match exactly.
Relaxed mode is the right default for almost all senders. Strict mode is for domain owners who want to stop even sibling subdomains from authenticating mail for each other, for example to isolate business units, or to defend against a compromised third party that signs as a delegated subdomain. Do not set s until aggregate reports confirm that every legitimate stream authenticates with the exact From domain.
Report processing
Aggregate reports (rua=)
- XML documents, usually generated daily by each receiver that reports. Expect the first reports 24+ hours after you publish the record.
- They contain counts for each source IP address, with the raw SPF and DKIM results, the alignment evaluation, and the disposition applied.
- They are delivered gzip-compressed to
mailto:URIs. Use a dedicated mailbox and automated parsing, never a person's inbox. - This is the main dataset for deployment decisions. It reveals every source that uses your domain in the RFC5322.From, including forgotten third parties.
Failure reports (ruf=)
- Sent immediately, for each failing message. If the domain is being spoofed at scale, the volume "could be several times the volume of your legitimate emails".
- They allow forensic analysis of individual messages, but many receivers do not send them (for privacy reasons), and they require capacity planning. Deploy
ruf=only after you understand your traffic from aggregate reports, or not at all.
External report destinations
If rua= or ruf= points to a domain other than the one that publishes the DMARC record, receivers check that the destination is authorized. The domain that receives the reports must publish:
example.com._report._dmarc.thirdparty.com. IN TXT "v=DMARC1"
This means that thirdparty.com agrees to accept reports about example.com. A wildcard form accepts reports for any domain, but opens a route for abuse:
*._report._dmarc.thirdparty.com. IN TXT "v=DMARC1"
Services that process DMARC reports rely on this mechanism. It is why pointing rua= at a vendor's address works without the vendor controlling your DNS.
Tooling
dmarc.org maintains directories of deployment tools and of code and libraries. Commercial report processors are listed under products and services.
- Record generators and wizards: dmarcian, EasyDMARC, DMARCLY, Fortra (Agari), Kitterman, Proofpoint, Global Cyber Alliance.
- Record checkers: the same vendors, plus Sendmarc, Valimail and Mimecast.
- Message reflectors and validators:
autoreply@dmarctest.org, aboutmy.email, Red Sift Investigate. - Code and libraries: the OpenDMARC milter, Mail::DMARC in Perl, mail-auth in Rust, the rddmarc scripts for parsing reports, dmarc-report-processor for conversion to CSV, and Lafayette for storing reports, among others.
Common failure scenarios
Forwarding
Simple forwarding rewrites the RFC5321.MailFrom (or keeps the original but sends from a new IP address), so SPF alignment is lost. DKIM survives forwarding only if the forwarder does not modify the signed content. Adding new headers is usually safe, but changing the Subject or body breaks the signature.
This is a core reason to authenticate with both protocols, and to rely on aligned DKIM above all. A message that keeps its DKIM signature intact passes DMARC after forwarding, even though SPF fails.
Mailing lists
Traditional lists modify messages (subject tags, footers), which breaks DKIM, and send from their own infrastructure, which breaks SPF alignment. Posts from a domain at p=reject then bounce for all subscribers. The known mitigations are:
| Mitigation | Mechanism | Trade-off |
|---|---|---|
| Strict forwarding | The list passes the message on untouched, so the original DKIM signature validates | Loses the subject tags and footers that list users expect |
| Original Authentication Results (OAR) or ARC | The list records the authentication state it saw when the message arrived, so that receivers can trust it | Requires adoption by receivers, which is limited but growing (ARC is the modern successor) |
| From rewriting (ownership transfer) | The list rewrites the RFC5322.From to its own domain and signs with DKIM as itself | The message is now "from" the list, which affects replies and address books |
From rewriting is what most large list software does today when the author's domain is at enforcement. If your users post to mailing lists, expect this behavior once you move beyond p=none.
The rollout path: none, quarantine, reject
dmarc.org describes a deployment process for senders in five steps:
- Deploy DKIM and SPF on every legitimate mail stream: corporate mail, the marketing platform, the CRM, the billing system, the support desk, all of them.
- Ensure alignment: check that the identifiers of each stream align with the RFC5322.From domain (the DKIM
d=and/or the RFC5321.MailFrom). - Publish
p=none, withrua=pointing at a dedicated report mailbox or processor. This has no effect on delivery. You are only collecting data. - Analyze the reports and fix the streams. Every source that fails is either (a) a legitimate sender to bring into alignment, or (b) abuse that enforcement will stop. Repeat until the aggregate reports show all legitimate mail passing.
- Escalate: move to
p=quarantine, at first with lowpctsampling (for RFC 7489 receivers), and raise it towardpct=100. Watch the reports for legitimate mail being quarantined. When there is none, move top=reject, again optionally raisingpctin steps.
Operational guidance for each phase:
- The
p=nonephase: plan for weeks, not days. Third-party senders (billing, HR, event platforms) appear slowly in reports, because some of them send rarely. - The
p=quarantinephase: failing legitimate mail goes to spam instead of disappearing, so recipients can still recover it. This safety net is what makes quarantine the mandatory intermediate step. Watch for forwarded and mailing-list traffic (see above), which will fail by design. - The
p=rejectphase: move to it only after aggregate reports show no legitimate messages being quarantined. The sending party sees a rejection (as a bounce), which helps detect broken streams, but anything you missed is lost. - Remember
sp=at every step. Changing the policy on the apex does not protect, or break, subdomains you have excluded.
Enforcement (quarantine or reject at 100%) is also the entry requirement for BIMI.
Related articles
- DMARC, on concepts, SPF and DKIM basics, alignment and the basic record
- BIMI, logo display, which requires DMARC enforcement
- Foundations of Email Deliverability
Check your own record
The free check reads what your domain publishes in DNS.
In this topic
All 13 in Authentication →