emailmarketing.net

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

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, rf and ri. pct was 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), and t (a testing flag, which replaces the pct=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=60 means that 60% of failing traffic is rejected and 40% is quarantined.
  • p=quarantine; pct=25 means that 25% is quarantined and 75% is treated as none.

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 (DKIM d= or the SPF RFC5321.MailFrom) only needs to share the Organizational Domain with the RFC5322.From domain. news.example.com aligns with example.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:

  1. 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.
  2. Ensure alignment: check that the identifiers of each stream align with the RFC5322.From domain (the DKIM d= and/or the RFC5321.MailFrom).
  3. Publish p=none, with rua= pointing at a dedicated report mailbox or processor. This has no effect on delivery. You are only collecting data.
  4. 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.
  5. Escalate: move to p=quarantine, at first with low pct sampling (for RFC 7489 receivers), and raise it toward pct=100. Watch the reports for legitimate mail being quarantined. When there is none, move to p=reject, again optionally raising pct in steps.

Operational guidance for each phase:

  • The p=none phase: plan for weeks, not days. Third-party senders (billing, HR, event platforms) appear slowly in reports, because some of them send rarely.
  • The p=quarantine phase: 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=reject phase: 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.

Check your own record

The free check reads what your domain publishes in DNS.

In this topic

All 13 in Authentication →