DMARC Tag Reference

Every tag that can appear in a DMARC record, what it defaults to when you leave it out, and which ones are worth setting deliberately.


A DMARC record is a single DNS TXT record published at _dmarc.example.com, containing semicolon-separated tag=value pairs. Only two tags are ever required — v and p — and every other tag has a default that applies when you omit it. Most real-world DMARC problems come from setting an optional tag without realising what it changes, so this reference states the default for each one alongside its valid values.

text
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100; adkim=r; aspf=r"

Tags at a Glance

TagPurposeValid valuesDefaultRequired
vProtocol versionDMARC1Yes, first
pPolicy for the domainnone, quarantine, rejectYes, second
spPolicy for subdomainsnone, quarantine, rejectinherits pNo
npPolicy for non-existent subdomainsnone, quarantine, rejectinherits spNo
pctPercent of failing mail the policy applies to0100100No
ruaAggregate report destinationComma-separated mailto: URIsnone sentNo
rufForensic report destinationComma-separated mailto: URIsnone sentNo
adkimDKIM alignment moder relaxed, s strictrNo
aspfSPF alignment moder relaxed, s strictrNo
foWhen to generate forensic reports0, 1, d, s (colon-separated)0No
rfForensic report formatafrfafrfNo
riAggregate reporting interval, secondsUnsigned integer86400No

v — Version

Must be the literal string DMARC1, and must be the first tag in the record. A record that does not begin with v=DMARC1 is not a DMARC record at all — receivers skip it entirely, and your domain is treated as having no policy.

text
v=DMARC1; p=none # valid p=none; v=DMARC1 # INVALID — v must come first v=DMARC1.0; p=none # INVALID — the value is exactly "DMARC1"

p — Policy

The instruction to receivers for mail that fails DMARC, and the second tag in the record. This is the tag that determines whether DMARC does anything at all.

  • p=none — take no special action. Monitoring mode: you get reports, delivery is unchanged. Publishing p=none provides no protection against spoofing.
  • p=quarantine — treat failing mail as suspicious, in practice the spam folder.
  • p=reject — refuse failing mail at SMTP time. The sender gets a bounce; nothing reaches the recipient. This is the goal state.
p must be the second tagRFC 7489 requires v first and p second. Some receivers are lenient about the ordering of p, but not all are — putting rua between them is a real source of records that work at one provider and are ignored at another.

sp — Subdomain Policy

Overrides p for subdomains of the record's domain. When absent, subdomains inherit p — this inheritance is why a single record at _dmarc.example.com protects mail.example.com, news.example.com and everything else beneath it.

text
# Enforce on the main domain, monitor subdomains while you inventory them v=DMARC1; p=reject; sp=none; rua=mailto:dmarc@example.com # Enforce everywhere (sp omitted, so subdomains inherit p=reject) v=DMARC1; p=reject; rua=mailto:dmarc@example.com

sp=none alongside p=reject is a common transitional state, and also a common oversight — attackers can and do spoof anything.example.com, so it should be a temporary step rather than a destination.

np — Non-Existent Subdomain Policy

A later addition that applies specifically to subdomains with no DNS records at all — no A, AAAA or MX. Since such a subdomain cannot legitimately send mail, np=reject is safe even while sp stays permissive.

text
v=DMARC1; p=reject; sp=none; np=reject; rua=mailto:dmarc@example.com

Support is narrower than the core tags — it is honoured by some large receivers and ignored by others — but it costs nothing to include and closes a real spoofing avenue during a rollout.

pct — Percentage

Applies the policy to a random sample of failing messages, letting you ramp enforcement gradually. pct=25 with p=reject means roughly a quarter of failing mail is rejected and the rest falls back to the next lower policy.

RecordSampled messagesRemainder
p=quarantine; pct=2525% quarantined75% treated as none
p=reject; pct=2525% rejected75% treated as quarantine
pct=0 is not a no-opp=reject; pct=0 does not disable enforcement — it downgrades every failing message to quarantine, the next policy down. If you want no action at all, use p=none. Note also that pct is deprecated in the draft revision of the DMARC specification, so treat it as a rollout aid rather than a permanent setting.

rua — Aggregate Report Address

Where daily XML summaries are sent. Accepts multiple comma-separated mailto: URIs, each optionally suffixed with ! and a size limit (k, m, g, t).

text
rua=mailto:dmarc@example.com rua=mailto:dmarc@example.com,mailto:reports@vendor.example rua=mailto:dmarc@example.com!10m # skip reports larger than 10 MB

This is the tag that makes DMARC usable. Without it you are enforcing blind. If the address is on a different organizational domain, that domain must publish an authorisation record — see How to Set Up DMARC Aggregate Reporting.

ruf — Forensic Report Address

Where per-message failure reports are sent. Same URI syntax as rua. In practice most major receivers never send these, and those that do are transmitting real message data — including recipient addresses — which carries privacy obligations you may not want. See RUA vs RUF before enabling it.

adkim and aspf — Alignment Mode

Control how strictly the authenticated domain must match the From: domain. r (relaxed, the default) allows any subdomain of the same organizational domain; s (strict) requires an exact match.

text
v=DMARC1; p=reject; adkim=s; aspf=s # strict both — breaks most ESP senders

Strict mode is narrower rather than more secure — relaxed already blocks every unrelated domain. Leave both out unless you have a specific reason. Full detail in DMARC Alignment Explained.

fo — Failure Reporting Options

Controls when a forensic report is generated. Only meaningful alongside ruf. Values are colon-separated:

  • 0 (default) — report only if both SPF and DKIM fail to produce an aligned pass.
  • 1 — report if either mechanism fails to produce an aligned pass. Far more reports.
  • d — report on any DKIM signature failure, regardless of alignment.
  • s — report on any SPF failure, regardless of alignment.
text
fo=1 # most common when forensics are wanted at all fo=d:s # DKIM and SPF failures reported separately

The default fo=0 is surprisingly narrow: a message where SPF fails but aligned DKIM passes generates nothing. Anyone enabling ruf for troubleshooting almost always wants fo=1.

rf — Report Format

The format for forensic reports. afrf (Authentication Failure Reporting Format, RFC 6591) is the only value in real use and is the default. There is effectively never a reason to set this tag.

ri — Reporting Interval

Requested seconds between aggregate reports, defaulting to 86400 (24 hours). It is a request, not a requirement — receivers may honour it or ignore it, and the large providers send daily regardless of what you ask for. Setting ri=3600 hoping for hourly reports will not produce them.

Syntax Rules That Break Records

  • Published at the wrong name. The record belongs at _dmarc.example.com, not example.com. In most DNS UIs the host field should read _dmarc.
  • More than one DMARC record. Two TXT records at _dmarc starting with v=DMARC1 is a fatal error — receivers treat the domain as having no policy rather than picking one.
  • Unknown tags. Receivers ignore tags they do not recognise, so a typo like rau= silently disables reporting rather than raising an error.
  • Whitespace in URIs. rua=mailto: dmarc@example.com — the space after the colon invalidates it.
  • Smart quotes. Pasting from a document can substitute typographic quotes for ASCII ones, producing a record that looks correct and parses as garbage.
  • A trailing semicolon is permitted and harmless.
bash
# Verify what is actually published dig +short TXT _dmarc.example.com # Two records returned means the policy is broken — expect exactly one dig +short TXT _dmarc.example.com | grep -c DMARC1

Records for Common Situations

text
# Day one — monitoring only, full visibility, zero delivery risk v=DMARC1; p=none; rua=mailto:dmarc@example.com # Mid-rollout — partial enforcement while subdomains are inventoried v=DMARC1; p=quarantine; sp=none; pct=50; rua=mailto:dmarc@example.com # Target state for a sending domain v=DMARC1; p=reject; rua=mailto:dmarc@example.com # Parked domain that should never send mail at all v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; rua=mailto:dmarc@example.com

The parked-domain record is the one case where strict alignment is genuinely appropriate: no legitimate mail exists to break. Pair it with an SPF record of v=spf1 -all and an empty DKIM policy.

To check what a domain currently publishes, use the DMARC Lookup tool; to assemble a new record without hand-writing the syntax, use the DMARC Generator.

Frequently Asked Questions

Which DMARC tags are actually required?

Only v=DMARC1 and p=. A record of exactly v=DMARC1; p=none is valid and complete. In practice you always want rua= as well, because without reports you cannot safely move beyond p=none.

Does tag order matter?

v must be first and p should be second. Everything after that can appear in any order. Receivers vary in how strictly they enforce the p position, so following the rule avoids a class of bug that only shows up at some providers.

What happens if I set a tag to an invalid value?

It depends on the tag. An invalid v or p invalidates the whole record and the domain is treated as having no DMARC policy. An invalid optional tag is generally ignored, with the default applied instead — which is why a bad pct value fails quietly rather than loudly.

Can I have separate DMARC records for subdomains?

Yes. A record published at _dmarc.news.example.com takes precedence over the parent record for mail from news.example.com. This is useful when a subdomain is handed to a marketing platform that needs a different policy during onboarding, though sp= handles the common case more simply.

Is pct still recommended?

As a temporary rollout aid, yes — it genuinely limits blast radius when first enabling quarantine or reject. It is deprecated in the draft revision of the spec, so do not treat it as a permanent part of your record; ramp through it and remove it.

Why is my DMARC record being ignored?

The usual causes are publishing at example.com instead of _dmarc.example.com, having two TXT records at _dmarc, or a record that does not start with v=DMARC1 — often because a DNS UI added the domain name to the host field automatically, producing _dmarc.example.com.example.com.

Related