DMARC Record Explained: Every Tag, Syntax Rule, and Common Mistake

A field-by-field breakdown of what actually goes into a DMARC TXT record, why each tag exists, and the syntax mistakes that quietly make a record invalid.

📅 Published August 2026· ⏳ 20 min read· ✍️ ToolsNovaHub Editorial Team
🛠️ Related tool: Open DMARC Lookup →

Anatomy of a DMARC Record

A DMARC record is, mechanically, nothing more than a DNS TXT record published at _dmarc.yourdomain.com, containing a single line of semicolon-separated tag=value pairs. That simplicity is deceptive — every one of those tags carries specific operational meaning, and getting even one syntax detail wrong can make receivers disregard the whole record. This guide goes through the record field by field, in the order most administrators actually reason about them, with the exact syntax rules RFC 7489 specifies.

A realistic, moderately configured record looks like this:

v=DMARC1; p=quarantine; sp=reject; pct=50; rua=mailto:dmarc-agg@example.com; ruf=mailto:dmarc-forensic@example.com; adkim=s; aspf=r; fo=1;

Every tag in that string is explained individually below, along with which ones are required, which are optional, and what receivers do when a tag is missing entirely versus present but malformed.

ToolsNovaHub Pro Tip
After editing a DMARC record, re-check it immediately with DMARC Lookup rather than assuming your DNS panel saved it correctly — a single stray character (a smart quote instead of a straight one is a classic culprit) silently breaks the whole record.
⚠️
Common Beginner Mistake
Publishing the record at _dmarc.yourdomain.com but leaving out the leading underscore, or placing it at the bare domain the way SPF is published. DMARC's location is fixed and non-negotiable — get the underscore-prefixed subdomain wrong and receivers will simply never find the record.

v — Version (Required)

The version tag must be the literal string DMARC1 and, by convention, is always the first tag in the record. It signals to a DNS resolver scanning through potentially multiple unrelated TXT records at the same name that this particular one is a DMARC policy. There is currently only one defined version, so in practice this tag never varies — but its presence and exact spelling are mandatory. A record missing v=DMARC1 or misspelling it is not treated as DMARC at all, regardless of what other tags follow.

p — Domain Policy (Required)

The policy tag is the core enforcement instruction and the only other tag besides v that's mandatory. It accepts exactly three values:

ValueMeaningTypical Use
noneTake no action; report onlyInitial monitoring phase
quarantineTreat as suspicious, typically routed to spamMid-rollout enforcement
rejectRefuse delivery outrightFull, mature enforcement

Any value outside those three — a typo like rejct, a capitalization mismatch some strict parsers won't accept, or an empty value — renders the record invalid in the eyes of a strict receiver. This is the tag most worth double-checking after any manual DNS edit.

sp — Subdomain Policy (Optional)

By default, the policy set in p applies both to the organizational domain and to every subdomain that doesn't publish its own separate DMARC record. The sp tag overrides that inheritance for subdomains specifically, letting an organization run a different — usually stricter — policy on subdomains than on the root domain. This matters because subdomains are a common target for abuse: an attacker registering a throwaway subdomain-style sender or exploiting a forgotten, unused subdomain benefits from any gap between root and subdomain enforcement. A common pattern is p=quarantine; sp=reject; — moderate enforcement on mail from the root domain, strict rejection on anything from a subdomain, since most organizations send far less legitimate mail from subdomains and can afford to be aggressive there sooner.

pct — Percentage of Enforcement (Optional, default 100)

The pct tag lets a domain owner apply the quarantine or reject policy to only a fraction of failing messages, chosen effectively at random by the receiver. It accepts an integer from 0 to 100. This is the mechanism behind gradual rollout: rather than flipping every failing message straight to reject, an administrator can set pct=10 initially, observe the impact, and raise it in stages — 25, 50, 75, 100 — over successive weeks. Because p=none takes no enforcement action regardless, pct has no observable effect until the policy is quarantine or reject; it's purely a rollout throttle for enforcement, not a sampling control for reporting, which continues at full volume from day one regardless of the pct value.

rua — Aggregate Report Address (Optional but strongly recommended)

The rua tag specifies where daily aggregate XML reports should be delivered, formatted as one or more mailto: URIs, comma-separated if there's more than one:

rua=mailto:dmarc-agg@example.com,mailto:reports@monitoring-vendor.com

Technically optional per the specification, omitting it in practice defeats most of DMARC's operational value, since the domain owner then has no visibility into authentication results at all — only the policy is enforced, blind. One subtlety worth knowing: if the address in rua is on a different domain than the one being protected, the receiving domain must publish an authorization record at _report._dmarc. plus the sender's domain, confirming it agrees to receive those reports — a mechanism to prevent DMARC from being used to flood arbitrary third-party mailboxes.

ruf — Forensic Report Address (Optional, limited support)

Where rua requests daily summary statistics, ruf requests per-message forensic reports containing details about individual authentication failures, sent close to real time rather than batched daily. In practice, support for ruf has declined significantly across major mailbox providers because forensic reports can include message content or headers with privacy implications; Gmail and several other large providers no longer send them at all regardless of whether ruf is configured. It's still valid to include, and some smaller providers and internal mail systems do honor it, but a domain owner shouldn't rely on it as a primary monitoring channel. Our dedicated article on DMARC Forensic Reports covers this in more depth.

adkim and aspf — Alignment Mode (Optional, default relaxed)

These two tags independently control how strictly DKIM and SPF alignment are evaluated. Each accepts r (relaxed, the default) or s (strict):

SettingStrict/Relaxed BehaviorExampleSecurity Impact
adkim=r (default)Any subdomain of the signing domain alignsDKIM signed by mail.example.com aligns with From: example.comMore compatible, slightly more permissive
adkim=sSigning domain must exactly match From: domainDKIM signed by mail.example.com does NOT align with From: example.comStronger, may break legitimate subdomain senders
aspf=r (default)Any subdomain of the envelope domain alignsSPF-authorized bounce.example.com aligns with From: example.comMore compatible
aspf=sEnvelope domain must exactly match From: domainSPF-authorized bounce.example.com does NOT align with From: example.comStronger, may break third-party transactional senders

The two tags are independent — a domain can run strict DKIM alignment alongside relaxed SPF alignment, or any other combination, depending on how tightly each authentication path is controlled. See DMARC Alignment for a deeper treatment with worked failure scenarios.

fo — Forensic Report Options (Optional, default 0)

The fo tag governs when forensic reports (subject to ruf being configured and honored) are actually generated. It accepts one or more colon-separated values:

ValueTriggers a Report When…
0 (default)The message fails DMARC evaluation overall
1Either SPF or DKIM fails, even if the message still passes DMARC overall
dThe DKIM signature fails to verify for any reason
sThe SPF check fails for any reason

fo=1 is the most commonly chosen non-default value, since it surfaces partial failures that fo=0 would otherwise hide — useful during a diagnostic period even though, again, actual delivery of these reports depends on receiver support.

rf and ri — Rarely Configured Tags

Two additional tags exist but are rarely set manually. rf specifies the format for forensic reports, with afrf (Authentication Failure Reporting Format) as the only value in practical use. ri requests an aggregate reporting interval in seconds, defaulting to 86400 (24 hours); in practice, most large mailbox providers send daily reports regardless of a smaller requested interval, since ri is explicitly a request rather than a binding requirement in the specification.

Syntax Rules That Actually Matter

Only One Record Per Domain
Exactly one TXT record starting with v=DMARC1 is permitted at _dmarc.yourdomain.com. Publishing two — often the result of a migration where an old record was never removed — makes the entire record invalid to strict receivers.
📝
Straight Quotes, Not Smart Quotes
Copying a DMARC string out of a word processor or chat app often substitutes curly "smart" quotes for straight ones inside mailto: values. DNS panels store the character literally, silently breaking the address.
🔍
No Spaces Inside a Tag Value
Spaces between tag=value pairs (after the semicolon) are fine and conventional; spaces inside a value, especially inside a mailto: address, are not and will break parsing.
🔐
TXT Record Length Limits
A single DNS TXT character-string is limited to 255 characters. Longer combined records (common with multiple rua/ruf addresses) are automatically split across multiple strings by properly behaving DNS software and reassembled by resolvers.

A Worked Example, Tag by Tag

Take this realistic mid-rollout record apart piece by piece:

v=DMARC1; p=quarantine; sp=reject; pct=50; rua=mailto:dmarc@example.com; adkim=r; aspf=r;
  • v=DMARC1 — declares this as a DMARC policy record
  • p=quarantine — mail failing DMARC from the root domain is routed to spam
  • sp=reject — mail failing DMARC from any subdomain is refused outright, a stricter stance since subdomains see less legitimate traffic
  • pct=50 — only half of failing messages actually receive the quarantine treatment right now, a mid-rollout throttle
  • rua=mailto:dmarc@example.com — daily aggregate reports land in this mailbox
  • adkim=r / aspf=r — both explicitly set to relaxed, matching the default but stated for clarity

Notice there's no ruf here — a deliberate choice given limited provider support, and no fo tag since it only matters when forensic reporting is actually happening.

Verifying a Record After Publishing

DNS propagation delay means a freshly published or edited record won't be visible everywhere instantly — typically within an hour depending on the record's TTL, though caching resolvers may hold an old value briefly longer. Once propagated, the fastest way to confirm every tag parsed the way you intended is a direct check with DMARC Lookup, which parses the live record exactly the way a receiving mail server would and flags missing required tags, unrecognized values, or multiple conflicting records automatically.

Building a Record Incrementally, Not All at Once

A common instinct when first learning DMARC syntax is to write out every tag at once — full alignment settings, forensic reporting, a specific pct value — before ever publishing anything. In practice, the more reliable approach is the opposite: start with the smallest working record, confirm it parses and reports correctly, then add complexity one tag at a time. Each addition is a small, individually verifiable change rather than a single large edit where, if something breaks, there are five possible culprits instead of one.

Step 1: v=DMARC1; p=none; rua=mailto:dmarc@example.com;
Step 2: + sp=quarantine;  (extend coverage to subdomains)
Step 3: + adkim=r; aspf=r;  (make default alignment explicit)
Step 4: + pct=25;  (once ready to begin enforcement)

Each of these intermediate states is a fully valid, independently checkable DMARC record — there's no requirement to reach a "final" configuration in one edit, and treating the record as something that evolves in small steps makes both DNS-side troubleshooting and enforcement rollout considerably less risky.

What Receivers Do With an Invalid Record

It's worth being specific about what actually happens when a DMARC record fails to parse, since the consequence is easy to underestimate. Most receivers don't reject the message outright or treat a malformed record as a policy failure — instead, they typically fall back to treating the domain as though it had no DMARC record published at all. That means all the intended protection silently evaporates: no alignment enforcement, no reporting, nothing — while the domain owner may still believe DMARC is active because a record technically exists in DNS. This is exactly why re-verifying syntax after every edit isn't optional caution; it's the only way to know the record is doing anything at all.

Comparing DMARC Syntax to SPF and DKIM Syntax

Anyone already comfortable with SPF or DKIM syntax will notice DMARC's tag=value structure is deliberately similar, though the underlying rules differ in ways worth being explicit about. SPF records are a single space-separated string of mechanisms evaluated left to right with no equals signs for most terms. DKIM selector records also use tag=value pairs but focus on cryptographic material (the p= tag there holds a public key, not a policy). DMARC's tag=value format most closely resembles DKIM's own record syntax, which isn't a coincidence — both were designed by overlapping working groups aiming for consistency across the broader email authentication ecosystem.

Checking TTL Before Making Frequent Changes

The TTL (time to live) value on the DMARC TXT record determines how long resolvers cache it before re-checking DNS, and it's worth checking before making several changes in quick succession during an active rollout. A long TTL — several hours or more — means changes propagate slowly, and testing the effect of a pct adjustment might not be visible everywhere for some time. Temporarily lowering the TTL during an active rollout period, then raising it again once the configuration stabilizes, is a common practice that makes iterative testing considerably faster without any downside once the record reaches its intended final state.

Related Reading in This Series

For the conceptual overview of why DMARC exists and how it fits with SPF and DKIM, start with What Is DMARC?. For the enforcement rollout across policy levels, read DMARC Policies (None, Quarantine, Reject). For how to interpret the reports generated along the way, see DMARC Aggregate Reports. To check your own domain's live record, open DMARC Lookup.

Reviewed by: ToolsNovaHub Editorial Team📅 Last updated: August 2026📜 Sourced from: RFC 7489

ToolsNovaHub tools are built and independently maintained with a focus on accurate, no-signup network and security utilities. Spotted an error? Let us know.

📋 Related Tools & Guides Comparison

ResourceTypeLink
DMARC LookupToolOpen Tool →
SPF LookupToolOpen Tool →
DKIM LookupToolOpen Tool →
What Is DMARC?GuideRead Guide →
DMARC Policies (None, Quarantine, Reject)GuideRead Guide →
🔗 Continue exploring: DMARC Lookup · SPF Lookup · DKIM Lookup · What Is DMARC? · DMARC Policies
Try it yourself — 100% free
🚀 Open DMARC Lookup

🔗 More Guides

FAQ

v=DMARC1; p=none; is technically the smallest valid record, though publishing it without a rua address defeats most of the practical purpose, since you'd receive no reports.
No, tag order is not enforced by the specification, though v=DMARC1 conventionally appears first and most published records follow a similar v, p, sp, pct, rua, ruf ordering for readability.
A semicolon is required between tags to separate them. A trailing semicolon after the final tag is optional and commonly included but not required by the specification.
Yes, multiple mailto: addresses can be comma-separated within the rua tag, and reports will be sent to each one, which is useful for routing copies to both an internal team and a monitoring tool.
Each address must be prefixed with mailto: — for example rua=mailto:dmarc@example.com — since the tag technically supports other URI schemes in the specification, though mailto is what's used in practice.
Yes, but the receiving domain must publish an authorization record at _report._dmarc.senderdomain.com pointing back, unless the rua address is on the same domain the DMARC record protects.
pct accepts any integer from 0 to 100. Values outside that range are invalid and receivers should treat the record as using the default of 100.
Technically the tag can be present, but since p=none takes no enforcement action regardless, pct has no observable effect until the policy is quarantine or reject.
adkim sets alignment mode specifically for DKIM evaluation; aspf sets it specifically for SPF evaluation. They can be configured independently — for example strict DKIM alignment with relaxed SPF alignment.
0 (report if the message fails DMARC overall, the default), 1 (report if either SPF or DKIM fails, even if DMARC passes), d (report on any DKIM signature failure), and s (report on any SPF failure). Multiple values can be colon-separated.
No. Forensic reports contain message-level detail with privacy implications, and most large mailbox providers including Gmail no longer send them regardless of the ruf tag being present.
The record is malformed. p is the only mandatory tag besides v, and its absence means most receivers will disregard the record as invalid DMARC.
Yes, DNS TXT records support multiple character-strings that concatenate automatically for values longer than 255 characters, the same mechanism long SPF records use.
The tag value itself should be written exactly as DMARC1 per the specification; while some resolvers are lenient about case, using the exact casing avoids any ambiguity.
86400 seconds, equal to 24 hours. Most large mailbox providers send aggregate reports daily regardless of a smaller requested interval, since ri is a request, not a guarantee.
Yes, after publishing the TXT record you can immediately check it with the free DMARC Lookup tool, which parses every tag and flags malformed or missing values.