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.
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100; adkim=r; aspf=r"Tags at a Glance
| Tag | Purpose | Valid values | Default | Required |
|---|---|---|---|---|
v | Protocol version | DMARC1 | — | Yes, first |
p | Policy for the domain | none, quarantine, reject | — | Yes, second |
sp | Policy for subdomains | none, quarantine, reject | inherits p | No |
np | Policy for non-existent subdomains | none, quarantine, reject | inherits sp | No |
pct | Percent of failing mail the policy applies to | 0–100 | 100 | No |
rua | Aggregate report destination | Comma-separated mailto: URIs | none sent | No |
ruf | Forensic report destination | Comma-separated mailto: URIs | none sent | No |
adkim | DKIM alignment mode | r relaxed, s strict | r | No |
aspf | SPF alignment mode | r relaxed, s strict | r | No |
fo | When to generate forensic reports | 0, 1, d, s (colon-separated) | 0 | No |
rf | Forensic report format | afrf | afrf | No |
ri | Aggregate reporting interval, seconds | Unsigned integer | 86400 | No |
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.
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. Publishingp=noneprovides 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.
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.
# 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.comsp=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.
v=DMARC1; p=reject; sp=none; np=reject; rua=mailto:dmarc@example.comSupport 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.
| Record | Sampled messages | Remainder |
|---|---|---|
p=quarantine; pct=25 | 25% quarantined | 75% treated as none |
p=reject; pct=25 | 25% rejected | 75% treated as quarantine |
p=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).
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 MBThis 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.
v=DMARC1; p=reject; adkim=s; aspf=s # strict both — breaks most ESP sendersStrict 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.
fo=1 # most common when forensics are wanted at all
fo=d:s # DKIM and SPF failures reported separatelyThe 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, notexample.com. In most DNS UIs the host field should read_dmarc. - More than one DMARC record. Two
TXTrecords at_dmarcstarting withv=DMARC1is 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.
# 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 DMARC1Records for Common Situations
# 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.comThe 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.