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.

Operationalesp-operatorsender

This article extends DMARC (concepts, alignment, the basic record) with the operational details a domain owner needs to deploy DMARC safely: the full tag set, subdomain policy, percentage sampling, alignment strictness, report handling, common failure scenarios, and the enforcement rollout path. Content 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

Key changes in the new RFCs (not breaking — records still begin v=DMARC1):

  • Removed tags: pct, rf, 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 (public suffix domain flag), t (testing flag, the replacement for the pct=0-style "monitor but don't enforce" use case).
  • Organizational Domain discovery: 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, capped at eight queries.

Because RFC 7489 semantics are still what most deployed records and receivers use, the tag reference below covers both.

Full tag reference

DMARC records use the extensible tag-value syntax borrowed 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 / reject
sp Policy for subdomains of the Organizational Domain sp=reject Defaults to the p value when absent
pct Percentage of failing messages the p policy is applied to pct=20 RFC 7489 only; removed in RFC 9989
rua URI(s) for aggregate reports rua=mailto:aggrep@example.com Comma-separate multiple URIs
ruf URI(s) for message-level failure ("forensic") reports ruf=mailto:authfail@example.com
adkim DKIM alignment mode adkim=s r (relaxed, default) / s (strict)
aspf SPF alignment mode aspf=r r (relaxed, default) / 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 aggregate report interval (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 Organizational Domain's p= policy. Publishing sp= lets you enforce differently across the organizational structure, for example:

  • p=none; sp=reject — still monitoring the apex domain, but rejecting spoofed mail on subdomains that send no mail.
  • p=reject; sp=none — apex locked down while a subdomain's mail streams are still being brought into alignment (a weak spot attackers can exploit; close it as soon as possible).

BIMI eligibility requires enforcement on both: p=quarantine|reject with no sp=none (see BIMI). Note that RFC 9989 adds np= so that non-existent subdomains can be rejected even while real subdomains are at a looser policy.

Percentage sampling (pct=, RFC 7489)

pct defines the percentage of failing messages the p= policy is applied to; the remaining messages are treated with the next-lower policy:

  • p=reject; pct=60 → 60% of failing traffic is rejected, 40% is quarantined.
  • p=quarantine; pct=25 → 25% quarantined, 75% treated as none.

This built-in throttle enables gradual enforcement: raise pct in steps at each policy level and watch the reports before going to 100. Under RFC 9989, pct is gone; the t=y testing flag covers the "publish enforcement intent without impact" case, and gradual rollout is done by moving between policy levels.

Alignment strictness (adkim= / aspf=)

Both alignment tags accept:

  • r (relaxed, default) — the authenticated domain (DKIM d= or 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 prevent even sibling subdomains from authenticating mail for one another (e.g., isolating business units, or defending against a compromised third party that signs as a delegated subdomain). Do not set s until aggregate reports confirm every legitimate stream authenticates with the exact From domain.

Report processing

Aggregate reports (rua=)

  • XML documents, typically generated daily per reporting receiver; expect the first reports 24+ hours after publishing the record.
  • Contain per-source-IP counts with SPF/DKIM raw results, alignment evaluation, and the disposition applied.
  • Delivered gzip-compressed to mailto: URIs — use a dedicated mailbox and machine parsing, never a human inbox.
  • This is the primary dataset for deployment decisions: it reveals every source (including forgotten third parties) using your domain in the RFC5322.From.

Failure reports (ruf=)

  • Sent immediately, per failing message — volume "could be several times the volume of your legitimate emails" if the domain is being spoofed at scale.
  • Enable message-level forensics, but many receivers do not send them (privacy), and they require capacity planning. Deploy ruf= only after you understand your traffic via aggregate reports — or not at all.

External report destinations

If rua=/ruf= point to a domain other than the one publishing the DMARC record, receivers verify authorization. The report-receiving domain must publish:

example.com._report._dmarc.thirdparty.com. IN TXT "v=DMARC1"

(meaning: thirdparty.com agrees to accept reports about example.com). A wildcard form accepts reports for any domain, at the cost of an abuse vector:

*._report._dmarc.thirdparty.com. IN TXT "v=DMARC1"

DMARC report-processing services rely on this mechanism — it is why pointing rua= at a vendor address works without them controlling your DNS.

Tooling

dmarc.org maintains directories of deployment tools (record generators/wizards: dmarcian, EasyDMARC, DMARCLY, Fortra/Agari, Kitterman, Proofpoint, Global Cyber Alliance; record checkers: the same vendors plus Sendmarc, Valimail, Mimecast; message reflectors/validators: autoreply@dmarctest.org, aboutmy.email, Red Sift Investigate) and code and libraries (OpenDMARC milter, Mail::DMARC in Perl, mail-auth in Rust, rddmarc report-parsing scripts, dmarc-report-processor for CSV conversion, Lafayette for report storage, among others). Commercial report processors are listed under products and services.

Common failure scenarios

Forwarding

Simple forwarding rewrites the RFC5321.MailFrom (or reuses the original from a new IP), so SPF alignment is lost. DKIM survives forwarding only if the forwarder does not modify the signed content — typically, adding new headers is safe; touching the Subject or body breaks the signature. This is a core reason to authenticate with both protocols and to treat aligned DKIM as the load-bearing one: 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) — breaking DKIM — and send from their own infrastructure — breaking SPF alignment. Posts from a p=reject domain then bounce for all subscribers. Known mitigations:

Mitigation Mechanism Trade-off
Strict forwarding List preserves the message untouched so the original DKIM signature validates Loses subject tags/footers list users expect
Original Authentication Results (OAR) / ARC List records the authentication state it observed at ingestion so receivers can trust it Requires receiver adoption; limited but growing (ARC is the modern successor)
From rewriting (ownership transfer) List rewrites RFC5322.From to its own domain and DKIM-signs as itself Message is now "from" the list; replies and address books are affected

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 past p=none.

The rollout path: none → quarantine → reject

The dmarc.org five-step sender deployment process:

  1. Deploy DKIM and SPF on every legitimate mail stream (corporate mail, marketing platform, CRM, billing system, support desk — all of them).
  2. Ensure alignment: verify each stream's identifiers align with the RFC5322.From domain (DKIM d= and/or RFC5321.MailFrom).
  3. Publish p=none with rua= pointing at a dedicated report mailbox or processor. No delivery impact; you are only collecting data.
  4. Analyze reports and fix streams. Every source that fails is either (a) a legitimate sender to bring into alignment, or (b) abuse that enforcement will stop. Iterate until the aggregate reports show all legitimate mail passing.
  5. Escalate: move to p=quarantine, initially with low pct sampling (RFC 7489 receivers), raising toward pct=100; monitor reports for legitimate mail being quarantined. When none is, move to p=reject — again optionally ramping pct.

Operational guidance for each phase:

  • p=none phase: budget weeks, not days. Third-party senders (billing, HR, event platforms) surface slowly in reports because some send infrequently.
  • p=quarantine phase: failing legitimate mail lands in spam rather than disappearing, so recipients can still rescue it — this is the safety net that makes quarantine the mandatory intermediate step. Watch for forwarding and mailing-list traffic (above), which will fail by design.
  • p=reject phase: only after aggregate reports show no legitimate messages being quarantined. Rejection is visible to the sending party (bounce), which aids detection of broken streams but means lost mail for anything you missed.
  • Remember sp= at every step: a policy migration 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

#authentication#dmarc#dns#alignment#reporting#rollout#forwarding#mailing-lists#dmarcbis