DMARC tags and policy

Every DMARC tag with its default, how alignment is actually evaluated, what the reports contain, and a rollout order that does not break your mail.

A DMARC record is a single DNS TXT record published at _dmarc under your domain, made of semicolon-separated tag-value pairs. This page lists every tag, what it does, and what happens when you leave it out — plus how alignment actually works, which is the part that decides whether your mail passes.

To check a specific domain instead, use the DMARC checker.

How a receiver evaluates DMARC

Four steps, in order. Understanding them explains almost every surprising result.

  1. Read the From: header domain. This is the domain DMARC protects — the one a human sees, not the envelope sender.
  2. Look up the DMARC record at _dmarc under that domain. If there is none, walk up to the organizational domain and use its record instead.
  3. Check alignment. SPF passed and its domain aligns with the From domain, or DKIM verified and its signing domain aligns. Either one is enough.
  4. Apply the policy if neither aligned, and send a report either way.

The critical point is step 3. DMARC never asks "did SPF pass?" in isolation. It asks whether a mechanism passed for the domain in the From header.

The tags

Tag Purpose Default if omitted
v Version. Must be DMARC1 and must come first. Required — record is invalid without it
p Policy for the domain: none, quarantine, reject. Required
sp Policy for subdomains. Inherits p
adkim DKIM alignment mode: r relaxed or s strict. r
aspf SPF alignment mode: r relaxed or s strict. r
pct Percentage of failing mail the policy applies to. 100
rua Where to send aggregate reports. mailto: URIs. No reports
ruf Where to send failure (forensic) reports. No reports
fo When to generate failure reports: 0, 1, d, s. 0
rf Failure report format. afrf
ri Aggregate report interval, in seconds. 86400 (daily)

Only v and p are required. Everything else has a default, and the defaults are mostly sensible — the two worth setting deliberately are rua and sp.

p and sp

p is the whole point of the record. none means take no action and report; quarantine means treat as suspicious, in practice spam; reject means refuse the message during the SMTP conversation.

sp exists because subdomains are the common spoofing target. Left out, subdomains inherit p — usually what you want. Set it explicitly when subdomains need different treatment, most often sp=reject on a parent still at p=none so unused subdomains are protected while you work through the main domain.

adkim and aspf

Alignment mode, and the difference is narrow but consequential:

  • Relaxed (r) — the organizational domains must match. mail.example.com aligns with example.com.
  • Strict (s) — the domains must match exactly. mail.example.com does not align with example.com.

Relaxed is the default and the right choice almost always. Strict breaks the moment a vendor signs with a subdomain you did not anticipate, and it buys very little: an attacker who controls a subdomain of your domain already has a bigger problem than alignment mode.

rua and ruf

rua receives aggregate reports: daily XML summaries, one per reporting receiver. This is the tag that makes DMARC useful rather than merely present.

ruf receives failure reports — near-real-time, per-message, and containing message headers. Most large receivers do not send them at all, for privacy reasons, so expect far fewer than you would guess. They can also contain personal data, which is worth thinking about before pointing ruf at a shared mailbox.

You can list several addresses, comma-separated. To receive reports at a domain you do not control, that domain has to publish an authorisation record — otherwise well-behaved reporters will refuse to send.

pct

Applies the policy to a random subset of failing mail. Designed for phased rollout: p=quarantine; pct=25 quarantines a quarter of failures and takes no action on the rest.

Two things to know. It is genuinely useful for a week or two while ramping. And it is a coin flip, so identical messages get different treatment — which makes debugging harder, not easier. Remove it once you are confident.

fo

Controls when failure reports are generated, when the receiver sends them at all:

Value Generate a report when
0 Both SPF and DKIM failed to align (the default)
1 Either failed to align — far more reports
d DKIM failed to verify, regardless of alignment
s SPF failed to verify, regardless of alignment

fo=1 is the common choice when actively debugging, because fo=0 hides the case where one mechanism aligned and the other silently broke.

Alignment, with examples

Say your From: is [email protected].

Scenario SPF domain DKIM d= Relaxed Strict
Sent from your own server example.com example.com Pass Pass
Sent via a platform signing as you bounce.vendor.net example.com Pass (DKIM) Pass (DKIM)
Platform signs with its own domain bounce.vendor.net vendor.net Fail Fail
Platform signs with your subdomain bounce.vendor.net mail.example.com Pass (DKIM) Fail

Row three is the one that catches people: the message is perfectly authenticated, and it still fails DMARC, because nothing authenticated your domain. Row four is why strict alignment costs more than it looks.

What the reports contain

Aggregate reports are compressed XML, typically daily, from each receiver that handled your mail. Each groups messages by source IP and sending domain and gives counts plus the SPF and DKIM results. No content, no subject lines, no recipient addresses. They answer one question well: who is sending as your domain, and is it aligning.

Failure reports are per-message and include headers, which is why they are increasingly rare. Do not build a process that depends on them.

Reading raw XML stops scaling quickly — a mid-sized domain gets dozens of files a day from a dozen providers. Our DMARC aggregation collects and groups them, which is the same job an XML parser and a spreadsheet do, minus the spreadsheet.

A rollout that does not break your mail

  1. Publish p=none with a rua address. No effect on delivery; reports start arriving.
  2. Read reports for two to four weeks. Build a list of every source sending as you.
  3. Fix or remove each source that fails alignment. This is the actual work, and it is where the time goes.
  4. Move to p=quarantine, optionally with pct while ramping. Watch reports.
  5. Move to p=reject and remove pct.
  6. Keep reading reports. A new vendor added later will break, and reports are how you find out before your customers do.

Things worth knowing

DMARC lives at _dmarc, not at the apex. A perfect record published on example.com instead of _dmarc.example.com does nothing. SPF does live at the apex, which is why this mistake is so common.

One record only. Two DMARC records at the same name means receivers treat the domain as having no valid policy.

Subdomains inherit, unlike SPF. DMARC applies down the tree via p or sp; SPF does not inherit at all. That asymmetry surprises almost everyone once.

p=none is not protection. A domain on p=none is exactly as spoofable as a domain with no DMARC. It is a measurement mode, and treating it as a finished project is the most common failure in the whole standard.