Introduction
A DMARC record is a TXT record published at the special DNS name _dmarc.yourdomain.com that tells the world how to handle authentication for your domain. It looks intimidating at a glance — a semicolon-separated string of two-letter tags — but it's actually a small, finite spec. Once you've read one, you've essentially read them all.
This article walks through every tag a DMARC record can contain, what it does, the valid values, and the trade-offs. Then we read a real-world record line by line so you can apply the same approach to yours.
Why this topic matters
Most DMARC operational mistakes trace back to misreading the record — setting a tag without understanding it, missing a critical tag, or assuming defaults that don't apply. The most expensive mistake people make is going to p=reject without realising what sp= is doing in the background, and bouncing legitimate mail on a subdomain they didn't think about.
Being fluent in the record format means you can audit any domain in 30 seconds and tell whether the policy is real, weak, or broken. For MSPs running audits that fluency is the difference between a five-minute screening and an hour-long investigation.
The anatomy of a DMARC record
Every DMARC record follows the same shape. Tags are separated by semicolons; the order doesn't matter; whitespace is allowed; quoting is optional.
“text v=DMARC1; p=quarantine; rua=mailto:[email protected]; pct=100 “
That's a valid record. Here's a more complete one:
“text v=DMARC1; p=reject; sp=reject; pct=100; adkim=r; aspf=r; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1; rf=afrf; ri=86400 “
Every tag, what it does
v= — Version (required)
Always DMARC1. If this tag is missing or has any other value, the record is invalid and receivers ignore it. Must be the first tag.
p= — Policy (required)
The headline tag. Three values:
The full breakdown lives in DMARC policy explained.
sp= — Subdomain Policy (optional, defaults to p= value)
Policy for subdomains of the published domain. Often overlooked. If you don't set it explicitly, subdomains inherit the parent policy — but you might want a different rule. See DMARC for subdomains.
pct= — Percentage (optional, defaults to 100)
Tells receivers to apply the policy to only this percentage of failing mail. Useful for progressive rollouts — start at pct=10, ratchet up. Has no effect when p=none.
adkim= — DKIM Alignment Mode (optional, defaults to r)
r(relaxed) — the DKIM signing domain just needs to share the parent organizational domain with the From headers(strict) — the DKIM signing domain must exactly match the From domain
DMARC alignment explained covers the trade-offs.
aspf= — SPF Alignment Mode (optional, defaults to r)
Same options as adkim=. Strict alignment requires the SPF envelope-from domain to exactly match the From header domain.
rua= — Aggregate Report URI (optional but strongly recommended)
A mailto: (or https:) destination for daily XML aggregate reports. Without this tag, you publish a policy but get no feedback on whether it's working.
You can list multiple destinations separated by commas. If the destination domain differs from the published domain, the receiving domain needs to publish a _report._dmarc.yourdomain.com TXT record authorising the external receiver — most platforms handle this for you.
ruf= — Forensic Report URI (optional)
A destination for forensic (per-failure) reports. Most receivers don't send these. Skip unless you have a specific use case.
fo= — Forensic Options (optional, defaults to 0)
Controls which failures generate forensic reports. Only meaningful if ruf= is also set.
0— generate a report only if both SPF and DKIM fail1— generate a report if either fails (most useful)d— generate if DKIM signature faileds— generate if SPF check failed
rf= — Report Format (optional, defaults to afrf)
Format for forensic reports. Always afrf in practice — no one supports other values.
ri= — Report Interval (optional, defaults to 86400)
How often (in seconds) you want aggregate reports. Default is daily (86400). Receivers may ignore values below 3600 (hourly).
How to read a real-world record
Here's a record pulled from a real domain. We'll read it tag by tag:
“text v=DMARC1; p=reject; sp=reject; pct=100; rua=mailto:[email protected],mailto:[email protected]; adkim=s; aspf=r “
v=DMARC1— Valid DMARC record marker.p=reject— Fully enforcing. Mail failing alignment is bounced at SMTP. This is the end-state policy most domains aim for.sp=reject— Subdomain policy also enforcing. Attackers can't pivot torandom.example.comand have their mail delivered.pct=100— Apply the policy to 100% of failing mail (no progressive rollout).rua=— Aggregate reports go to two destinations: an internal mailbox ([email protected]) and an external platform ([email protected]). The second destination implies they're using a managed DMARC service for parsing.adkim=s— Strict DKIM alignment. The DKIM signing domain must exactly match the From header. This is uncommon and aggressive — it suggests the domain owner has tight control over their senders.aspf=r— Relaxed SPF alignment. Standard.
In 30 seconds, that record tells you the domain is fully enforced, monitored externally, and run by an admin who knows what they're doing.
Step-by-step approach to writing your first record
- Decide on starting policy. For most domains, that's
p=nonefor the monitoring phase. - Choose a report destination. Best practice is a dedicated mailbox routed to a DMARC platform.
- Decide on subdomain policy. If you don't think about it, default behaviour applies — be intentional.
- Skip
ruf=unless you have a specific forensic-handling workflow. - Compose:
v=DMARC1; p=none; rua=mailto:[email protected]. - Publish at
_dmarc.yourdomain.comas a TXT record.
How to create a DMARC record step by step covers the DNS-side mechanics.
Best practices
- Always include
rua=. A policy without reporting is flying blind. - Always set
sp=explicitly. Don't rely on inheritance defaults. - Use
pct=for progressive rollouts, not as a permanent setting. A long-termpct=50is a half-enforced policy. - Don't enable
ruf=unless you have a downstream system that consumes it. Forensic reports can leak content from forwarded mail. - Validate after publishing. Use a DMARC record checker to confirm syntax — typos are the most common implementation failure.
Recommended next step
Look up your own domain's current DMARC record. From a terminal:
“bash dig +short TXT _dmarc.yourdomain.com “
Or use any online DMARC lookup tool. Read the result tag by tag. If you can't explain every tag's presence or absence, that's where the work is.
If you don't have a record yet, the step-by-step creation guide takes you from zero to published in under 30 minutes.
FAQ
Where exactly does the record live?
At the DNS name _dmarc.yourdomain.com, as a TXT record. The underscore is required. The trailing dot can be omitted (DNS will add it).
Can a domain have multiple DMARC records?
No. Only one valid TXT record at _dmarc.yourdomain.com is allowed. Multiple records cause receivers to ignore all of them. Common DMARC errors covers this gotcha.
What if my domain doesn't send email?
Publish v=DMARC1; p=reject; sp=reject; rua=mailto:[email protected] anyway. A non-sending domain at p=reject is unspoofable, which is exactly what you want.
Can I split the record across multiple TXT entries?
No. The record must be a single TXT entry. DNS allows you to split a TXT value across multiple quoted strings (a DNS-level convenience), but the parsed result must be one DMARC record.
What's the difference between organizational domain and From domain?
The organizational domain is the public-suffix-aware "root" of your domain — brand.com for mail.brand.com. Relaxed alignment compares against the organizational domain; strict compares the literal hostname. The distinction matters for subdomain policies.
Final thoughts
A DMARC record is one line of DNS text that doubles as your domain's public security posture. Reading one well takes about as long as reading a single short paragraph; writing one well takes about as long as writing the same paragraph carefully. The work is in what you publish, not how — and that's the work covered by the rest of the academy.
Once you can read any DMARC record at a glance, every audit, every troubleshooting session, and every progressive rollout becomes substantially faster. It's worth the 15 minutes to get fluent.