How to Create a DMARC Record (Tags, Syntax & Examples, p=none → p=reject)
A DMARC record is a single DNS TXT record published at the host
_dmarc.yourdomain.com. To create one, publish
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com as a TXT record and you
have a valid, monitoring-mode DMARC record.
That is the whole answer for getting started — but knowing how to create a DMARC record that actually protects your domain means understanding the tags, the policy levels, and how to escalate from monitoring to enforcement without breaking legitimate mail. This guide is for IT admins and founder-operators standing up DMARC for the first time, often under pressure from the Google and Yahoo bulk-sender rules in force since February 2024.
You will get the complete current tag reference, three worked examples, the
exact DNS steps, and the staged rollout from p=none to p=reject.
Everything here is current for DMARCbis — RFC 9989, 9990, and 9991,
published May 2026 — which no top-five competitor guide reflects yet.
What is a DMARC record?
A DMARC record is a DNS TXT record that tells receiving mail servers how to
handle email that fails authentication — and where to send reports about it.
It lives at the host _dmarc.yourdomain.com and always begins with
v=DMARC1.
DMARC builds on two existing standards: SPF (RFC 7208), which
authorizes sending IPs, and DKIM (RFC 6376), which
cryptographically signs messages. DMARC adds three things on top — alignment
(does the authenticated domain match the visible From: domain?), policy
(what should receivers do when alignment fails?), and reporting (where to
send the data). A DMARC record does not sign or send mail; it is an
instruction plus a reporting address.
The record lives at an underscore-prefixed host: _dmarc.<your-domain>. For
the organizational domain example.com, that is _dmarc.example.com.
Subdomains are covered by the organizational-domain record unless you publish
a separate one for them.
There is also a compliance reason to publish one. Google and Yahoo require a
DMARC record for bulk senders as of February 1, 2024 — Google sets the
threshold at 5,000 or more messages per day to personal Gmail accounts, with a
minimum policy of p=none.
DMARC is defined by RFC 9989 (DMARCbis core), which replaced the 2015 informational RFC 7489 in May 2026. The tag grammar below is cited against RFC 9989 throughout.
What does a DMARC record look like? (3 worked examples)
Here is a valid DMARC record:
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com. That single line —
published as a TXT record at _dmarc.yourdomain.com — is the minimal record
most domains start with. This is the DMARC record example people look for
first, so here are three, from minimal to full enforcement.
Minimal valid DMARC record
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com Three tags: the version (v=DMARC1), the policy (p=none, monitoring only),
and an aggregate report address (rua). Note that we omit pct= — the
percentage tag that older guides still append as pct=100. Under RFC 9989,
pct= is deprecated and receivers ignore it. Leaving it out is the freshness
signal that your record is DMARCbis-shaped.
Recommended starter record
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; adkim=r; aspf=r This adds explicit relaxed-alignment modes (adkim=r, aspf=r). They are the
defaults, so the record behaves identically to the minimal one — but spelling
them out makes the record self-documenting and ready for the rollout steps
later. Point rua at a mailbox you actually monitor.
Full enforcement record
v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc@yourdomain.com; adkim=r; aspf=r This is the destination state: p=reject blocks failing mail, and sp=reject
applies the same to subdomains. For tighter hardening you can add np=reject
(reject mail from non-existent subdomains) — a DMARCbis tag covered in the tag
reference below.
12.8% of the top 5.5M domains enforce DMARC with p=quarantine or p=reject. Publishing a record is step one; escalating from p=none is where most teams stall.
DMARC record syntax — the tag/value grammar
A DMARC record is a list of tag=value pairs separated by semicolons. The
v=DMARC1 version tag MUST come first, the p= policy tag MUST come second,
and the remaining tags may appear in any order.
The grammar is defined in RFC 9989 §4.7 (DMARC Policy Record Format), which carries forward what RFC 7489 §6.3 specified in 2015. Three rules matter when you write the DMARC record format by hand:
- Order:
v=DMARC1first,p=immediately after. Everything else is free-order. - Unknown tags are ignored: receivers MUST skip tags they do not
recognize (RFC 9989 §4.7). This forward-compatibility rule is why a
lingering deprecated
pct=does not break a record — it is simply ignored. - One record per domain: publishing two TXT records at
_dmarcinvalidates the policy entirely (see Common mistakes).
Case and whitespace around the separators are tolerated, and the trailing semicolon is optional — the UK NCSC’s published starter record omits it.
DMARC record tags reference (complete current table)
A DMARC record supports fourteen tags. Only two — v and p — are required;
the rest tune reporting, alignment, and subdomain handling. The table below is
the complete current reference, with each tag anchored to its RFC section.
| Tag | Name | Required | Default | Values / notes | RFC anchor |
|---|---|---|---|---|---|
v | Version | Yes | — | DMARC1 (must be first) | RFC 9989 §4.7 |
p | Policy | Yes | — | none / quarantine / reject (must be second) | RFC 9989 §4.7 |
sp | Subdomain policy | No | inherits p | none / quarantine / reject | RFC 9989 §4.7 |
np | Non-existent-subdomain policy | No | inherits sp | none / quarantine / reject — DMARCbis new | RFC 9989 §4.7 |
rua | Aggregate report URI | No | — | mailto: (one or more, comma-separated) | RFC 9990 |
ruf | Failure report URI | No | — | mailto: — increasingly deprecated by ESPs | RFC 9991 |
adkim | DKIM alignment mode | No | r (relaxed) | r (relaxed) / s (strict) | RFC 9989 §4.7 |
aspf | SPF alignment mode | No | r (relaxed) | r (relaxed) / s (strict) | RFC 9989 §4.7 |
fo | Failure reporting options | No | 0 | 0 / 1 / d / s (colon-joined) | RFC 9991 |
t | Testing mode | No | n | y (one-step downgrade) / n — DMARCbis new, replaces pct | RFC 9989 §4.7 |
psd | Public Suffix Domain flag | No | u (unknown) | y / n / u — DMARCbis new, rarely set | RFC 9989 §4.7 |
pct | Percentage | No | 100 | Deprecated (RFC 9989) — removed; receivers ignore it | RFC 7489 §6.3 (historical) |
rf | Report format | No | afrf | Deprecated (RFC 9989) — only afrf was ever used | RFC 7489 §6.3 (historical) |
ri | Aggregate report interval | No | 86400 | Deprecated (RFC 9989) — receivers set their own cadence | RFC 7489 §6.3 (historical) |
The prose below covers the DMARC tags explained for the ones people search
for individually. Most domains only ever touch four — v, p, rua, and
eventually sp/np — so skip ahead to the DNS steps and come back for the rest
as you need them.
p — the policy tag
The p= tag is the one instruction that matters. It tells receivers what to do
with mail that fails DMARC: none (monitor), quarantine (send to spam), or
reject (block). It MUST appear immediately after v=DMARC1.
Choosing and escalating the policy
is the core of the rollout further down.
rua — aggregate report address
rua= is where daily aggregate XML reports are delivered, for example
rua=mailto:dmarc@yourdomain.com. These reports list every IP that sent mail
as your domain and whether it aligned. Without rua, your record is valid but
you receive no data — you are flying blind. RFC 9990 governs the aggregate
report schema and delivery.
ruf — failure report address
ruf= requests per-message failure (forensic) reports. It is increasingly
deprecated by mailbox providers, and the reports carry privacy-sensitive
message content, so RFC 9991 §7 adds expanded privacy guidance. Most domains
set only rua and leave ruf out entirely.
sp and np — subdomain & non-existent-subdomain policy
sp= sets the policy for subdomains; if absent, subdomains inherit p. np=
is a DMARCbis addition (RFC 9989 §4.7) that sets the policy for non-existent
subdomains — mail claiming a subdomain that returns NXDOMAIN. It takes the same
none / quarantine / reject values as p (see the reference table above).
If unset, np= defaults to whatever sp= is. A common hardening pattern is
p=quarantine; sp=quarantine; np=reject to block fabricated subdomains
outright while keeping real ones softer.
For the full inheritance rules and edge cases, see sp= and np= subdomain policies explained.
adkim / aspf — alignment modes
adkim= and aspf= control how strictly the authenticated domain must match
the From: domain. Relaxed (r, the default) allows subdomains to align with
the organizational domain; strict (s) requires an exact match. Relaxed is the
safe default — strict alignment rejects legitimate subdomain senders unless
every one is exactly aligned.
fo — failure reporting options
fo= controls when failure reports are generated: 0 (default — report only
when both SPF and DKIM fail), 1 (report when either fails), d (DKIM
failures), or s (SPF failures). Values are colon-joined, e.g. fo=1:d. It
only matters if you also set ruf.
t, psd — the DMARCbis additions (and the deprecated pct, rf, ri)
t= (testing mode) and psd= (Public Suffix Domain flag) are DMARCbis
additions defined in RFC 9989 §4.7.
| Tag | Values |
|---|---|
t= | y = policy is provisional; receivers downgrade enforcement one step. n = operational (default). |
psd= | y = this domain is a public suffix. n = it is not. u = unknown (default). |
t=y is the one-step downgrade that replaces the old pct= rollout role: a
p=reject record with t=y is treated as p=quarantine by receivers. psd=
is for Public Suffix Operators only — almost no operator needs it.
pct, rf, and ri are gone in RFC 9989. The working group found pct
was applied accurately only at 0 or 100; rf had a single value (afrf)
that was ever used; and receivers ignored ri in practice. For the full
DMARCbis breakdown of every removed and added tag, see
the day-one DMARCbis breakdown.
DMARCbis: what changed for record authors (May 2026)
DMARCbis — published May 2026 as RFC 9989, 9990, and 9991 — replaced the 2015
RFC 7489 and promoted DMARC to the IETF Standards Track. For someone creating a
record today, the practical change is small: keep v=DMARC1, drop the
deprecated pct/rf/ri tags, and learn three new ones — np, psd, and
t.
The substantive deltas for a record author:
- Removed:
pct,rf,ri. Added:np(non-existent-subdomain policy),psd(public-suffix flag), andt(binary testing mode that replaces the percentage ramppctused to provide). - Tree walk replaces the Public Suffix List: organizational-domain discovery now uses a DNS tree walk capped at eight queries (RFC 9989 §4.10), not the Mozilla-hosted PSL. The full DMARCbis breakdown walks a worked example.
- No version bump: existing
v=DMARC1; p=…records stay valid. There is no “DMARC2,” and no forced migration.
Receiver adoption is still rolling out — as of mid-2026 only United Internet AG
(GMX, mail.com, WEB.DE) was reported to emit DMARCbis-format reports, and
Google, Microsoft, and Yahoo had not published implementation specs. That is
fine: a DMARCbis-shaped record (no pct, with relaxed defaults) works under
both old and new receivers, so publish it now.
This is the differentiator. Microsoft Learn and Mimecast still teach pct= as
a live testing lever; under RFC 9989 it is removed.
How to create and add a DMARC record to your DNS (step-by-step)
To add a DMARC record: log in to your DNS provider, create a new TXT record,
set the host to _dmarc, paste your record value (for example
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com), save, and verify with a
DMARC checker after propagation. Here is the DMARC record setup, step by
step — the host and value are identical at every provider; only the UI differs.
How to create a DMARC record
-
Confirm SPF and DKIM exist first. DMARC depends on them — verify both are configured and passing for your sending domain with a SPF checker before you publish. If alignment is broken, your first reports will show legitimate mail failing.
-
Choose your starting policy —
p=nonefor monitoring. Every domain starts here: it collects reports without acting on any mail. -
Build the record value — paste
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com, or generate one with the tags you want. -
Open your DNS provider and create a new TXT record. Do not create a CNAME — a CNAME at
_dmarcconflicts with the TXT record and the policy will not publish. -
Set host =
_dmarcand value = your record string. Leave TTL at the default (or lower it to 300 seconds before a future edit so changes propagate faster). -
Save and verify after 15 to 60 minutes of propagation, using
digor a DMARC checker (next section).
A note on hosts: some providers auto-append your domain. On GoDaddy in
particular, enter the host as _dmarc — not _dmarc.yourdomain.com — or the
record lands at _dmarc.yourdomain.com.yourdomain.com and checkers report no
record. The host and value are the same in Cloudflare, Route 53, GoDaddy, or
Azure; only the panel layout changes. For the exact click-path on Google
Workspace, see our
Google Workspace DMARC setup walkthrough.
Verify your DMARC record is published correctly
Verify your DMARC record with dig +short TXT _dmarc.yourdomain.com — if it
returns your v=DMARC1; … string, the record is live. If it returns nothing,
the record has not propagated or the host name is wrong.
# Linux / macOS — dig (the +short flag strips DNS metadata)
dig +short TXT _dmarc.yourdomain.com
# Linux / macOS — host
host -t TXT _dmarc.yourdomain.com
# Windows — nslookup (you MUST set -type=TXT, or it defaults to A and finds nothing)
nslookup -type=TXT _dmarc.yourdomain.com
# Windows PowerShell
Resolve-DnsName -Name "_dmarc.yourdomain.com" -Type TXT | Select-Object -ExpandProperty Strings The +short flag strips DNS metadata and returns only the record value. On
Windows, nslookup defaults to an A-record query, so you must pass
-type=TXT or it will find nothing. If the lookup returns no DMARC record,
the usual causes are: propagation lag (wait and retry), the wrong host
(yourdomain.com instead of _dmarc), or a CNAME/TXT conflict at _dmarc.
Prefer the browser? Confirm it with our
free DMARC checker — paste your domain and it returns
the parsed record and any syntax problems. If the parsed checker says no record
was found, run a raw TXT record lookup to see exactly what
resolvers are returning at _dmarc.yourdomain.com.
Choose your DMARC policy: p=none, p=quarantine, p=reject
DMARC has three policies. p=none monitors without acting; p=quarantine
sends failing mail to spam; p=reject blocks it outright. Move up only after
your reports confirm that legitimate mail passes. RFC 9989 §4.7 defines the
three values; DMARCbis formalizes p=none as Monitoring Mode and
quarantine/reject as Enforcement.
p=none — monitor only
p=none is DMARC policy none: receivers take no enforcement action and
simply send you aggregate reports. It is the default entry point and exists so
you can see who sends mail as your domain before you enforce anything.
p=quarantine — soft enforcement
p=quarantine tells receivers to deliver failing mail to the spam folder. It
is the safe intermediate step — failures are recoverable from spam rather than
lost, so you can catch a missed legitimate sender without bouncing real mail.
p=reject — full enforcement
p=reject blocks failing mail at the server. It is the destination state and
the prerequisite for BIMI. Reach it only once your reports show every
legitimate source aligned.
| Policy | Failing mail | Protection | When to use |
|---|---|---|---|
p=none | Delivered normally | None (monitoring) | Day one — collect reports, identify all senders |
p=quarantine | Sent to spam | Partial | After reports show legitimate mail aligning |
p=reject | Blocked outright | Full | Once every legitimate source passes, aligned |
| Our recommendation | Start at p=none, escalate to p=reject | — | p=reject is the destination, not a permanent resting state |
Roll out from p=none to p=reject without breaking mail
Roll out in stages: publish p=none, read aggregate reports until every
legitimate sender passes SPF or DKIM aligned, then step to p=quarantine,
then p=reject. Use t=y (testing mode) — not the deprecated pct= — as
your brake at each step.
The readiness criterion is signal-based, not calendar-based. The authoritative guidance (M3AAWG, UK NCSC) is to advance when all known legitimate sources are identified and aligned and no new sources appear in reports — not after a fixed number of days. UK NCSC: move to quarantine “as soon as you are confident DKIM and SPF are configured correctly, and all known legitimate sources of email for your domain have been added to your records.”
Time heuristics are secondary and vary by source: NCSC reports many
organizations move off p=none after about six to eight weeks; dmarcian
suggests advancing at a 98% compliance rate sustained for at least 30 days.
Lead with the signal, not the number.
Because pct= is deprecated, the percentage-ramp playbook has no in-protocol
successor under RFC 9989. Instead, use t=y for a dry run and sp= (or a
dedicated sending subdomain) to scope risk. The ladder is:
p=quarantine; t=y → p=quarantine → p=reject; t=y → p=reject The common breakage point is third-party senders: this is the stall point where
most domains stop, with 17.6% of the top 5.5M stuck at p=none largely because
unidentified senders are never reconciled. Forwarding breaks SPF and mailing
lists break DKIM; ARC (RFC 8617) mitigates
both for indirect flows.
17.6% of the top 5.5M domains are stuck at p=none — visibility without protection.
Not sure whether your reports say you are ready to advance? Our
p=none escape plan answers the one question every
competitor guide leaves open: how do I know I can move off p=none safely?
Common mistakes when creating a DMARC record
The most common DMARC record mistakes are: publishing more than one record at
_dmarc, using a CNAME instead of a TXT record, putting the record at the
wrong host, omitting rua so no reports arrive, and stray spaces or trailing
characters that corrupt the value.
- Multiple records at
_dmarc— two TXT records invalidate the policy and receivers ignore all of them. Keep exactly one; merge any extra tags into it. - CNAME instead of TXT — a CNAME at
_dmarccollides with the TXT record; DNS rejects it with an error like “RRset with conflicting type present.” - Wrong host — publishing at
yourdomain.com, or at_dmarc.yourdomain.comon a provider that auto-appends the domain (so it doubles), instead of plain_dmarc. - Missing
rua— the record is valid but you receive zero reports, so you have no visibility into who sends as your domain. - Stray whitespace or trailing characters — copy-paste artifacts that break parsing. Paste the record into a checker before you trust it.
Each of these is a real, recurring failure reported on the Cloudflare, Atlassian, and deSEC community forums — not a hypothetical.
Who requires a DMARC record? (compliance, briefly)
DMARC is required by several mandates: Google and Yahoo for bulk senders (Feb
1, 2024), CISA BOD 18-01 for US federal agencies (p=reject), and PCI DSS
v4.0.1 Req 5.4.1 (Mar 31, 2025), which names it as an example anti-phishing
control. NIS2 and DORA expect it implicitly rather than by name.
| Mandate | DMARC required? | Policy level | Effective date |
|---|---|---|---|
| Google (bulk, ≥5,000/day) | Yes | p=none minimum | Feb 1, 2024 |
| Yahoo (bulk, no numeric threshold) | Yes | p=none minimum | Feb 2024 |
| CISA BOD 18-01 (US federal) | Yes | p=reject | Oct 16, 2017 |
| PCI DSS v4.0.1 §5.4.1 | Example control, not named | — | Mar 31, 2025 |
| NIS2 (EU) | Implied, not named | — | Transposition Oct 17, 2024 |
NIS2 is widely misreported: its transposition deadline was 17 October 2024, and the directive implies email-security controls rather than naming DMARC. Any “2026” NIS2 date refers to a separate amendment proposal, not a deadline — our NIS2 email security guide covers the distinction in full.
The compliance pressure shows in the data: .gov domains hit 76.4% DMARC adoption (CISA-driven) against 30.4% across the broader internet (DMARCguard scan of 5,499,028 domains, February 2026). The .edu sector tracks even higher at 84.0%.
76.4% of .gov domains publish DMARC (CISA BOD 18-01-driven) vs 30.4% across the broader internet
Frequently Asked Questions
How do I generate a DMARC record?
Use a DMARC generator that builds the v=DMARC1; p=...; rua=... string for
you, then publish it as a TXT record at the host _dmarc in your DNS provider.
A monitoring-mode starter is v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com.
Verify it afterward with dig or a DMARC checker.
How do I add a DMARC record to my domain?
Create a TXT record (not a CNAME) at the host _dmarc in your DNS provider,
paste your record value, and save. After 15 to 60 minutes of propagation,
confirm it is live with dig +short TXT _dmarc.yourdomain.com or a
browser-based DMARC checker.
What is an example of a DMARC record?
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com is a minimal valid DMARC
record. It declares the version (v=DMARC1), the policy (p=none for
monitoring only), and an aggregate report address (rua) where daily XML
reports are sent.
Can I have more than one DMARC record per domain?
No. A domain may have exactly one DMARC TXT record at
_dmarc.yourdomain.com. If two or more are published, the policy is invalid
and receivers ignore all of them, leaving the domain unprotected. Keep a single
record and merge any extra tags into it.
How much does DMARC cost?
Publishing a DMARC record is free — it is a single DNS change at your provider. The cost, if any, comes from reading the aggregate reports, where monitoring tooling helps. DMARCguard’s free tier covers report parsing and sender identification at no charge.
How long until DMARC reports start arriving?
Aggregate (rua) reports arrive on a daily cadence, typically 24 to 72 hours
after you publish a valid rua address. If none arrive after 72 hours, check
that the rua mailbox accepts mail and that any external-destination
verification record is in place (RFC 9990 §4).
Do I need ruf as well as rua?
No. rua (aggregate reporting) is what you want and what every domain should
set. ruf (failure/forensic reporting) is increasingly deprecated by mailbox
providers and carries privacy-sensitive message content (RFC 9991 §7). Most
domains set only rua.
Conclusion
Creating a DMARC record comes down to a few durable points:
- A DMARC record is one TXT record at
_dmarc.yourdomain.com, starting withv=DMARC1. - Start at
p=none, verify withdig +short TXT _dmarc.yourdomain.com, and escalate top=rejecton signal — when reports show legitimate mail aligned — not on a calendar. - Drop the deprecated
pct,rf, andritags; under DMARCbis (RFC 9989) they are removed, andt=yis the rollout brake.
Once it is published, verify your record with our DMARC checker to confirm it parses and the policy is live.
And if you want to keep the whole monitoring stack at zero cost, our free DMARC tooling roundup covers what each free tier actually includes.