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.
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.
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.