A DMARC record is one DNS TXT record at _dmarc.yourdomain.com that starts with v=DMARC1, followed by a policy such as p=none and optional tags separated by semicolons. The shortest useful record is v=DMARC1; p=none; rua=mailto:dmarc@example.com. RFC 7489 section 6.3 defines 11 tags; only v and p are required.
This page lists every tag with its default, shows records that work and records that do not, and ends with the mistakes we found in real records. If you would rather fill in a form, the DMARC record generator builds the record for you.
Where the record goes
The host name is always _dmarc in front of the domain that appears in your From addresses.
Host: _dmarc.example.com
Type: TXT
Value: v=DMARC1; p=none; rua=mailto:dmarc@example.com
In most DNS panels you type only _dmarc in the host field, because the panel appends the domain. Typing _dmarc.example.com there can create _dmarc.example.com.example.com. Check with dig +short TXT _dmarc.example.com after you save.
Three rules decide whether a receiver finds your record at all:
- One record only. If a receiver gets two TXT records that start with
v=DMARC1at the same name, RFC 7489 section 6.6.3 says policy discovery stops and DMARC is not applied. Two records are worse than one weak record. - Subdomains inherit. A message from
news.example.comwith no record at_dmarc.news.example.comfalls back to the record at_dmarc.example.com, and thesptag there applies. - Long values may be split. A TXT record can hold several quoted strings, and DNS joins them with no space. One record in our scan splits in the middle of a word, as
"...rua=mailt" "o:reports@example.com", and it still reads asrua=mailto:once joined.
DMARC record examples, from monitoring to reject
These are the records most domains move through. Each is valid as written.
Monitoring, with aggregate reports:
v=DMARC1; p=none; rua=mailto:dmarc@example.com
Quarantine for a slice of failing mail while you watch reports (pct is an RFC 7489 tag; see the RFC 9989 section below):
v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc@example.com
Full enforcement, subdomains included, reports to your own mailbox and a reporting service:
v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc@example.com,mailto:abc123@reports.example.net
A parked domain that never sends mail:
v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s
That last one is not invented. It is the record example.com published on 19 October 2026, when we read it with dig. Pair it with v=spf1 -all at the root.
Some real records from the same day, for comparison:
_dmarc.google.com v=DMARC1; p=reject; rua=mailto:mailauth-reports@google.com
_dmarc.github.com v=DMARC1; p=quarantine; sp=reject; pct=100; rua=mailto:dmarc@github.com; ruf=mailto:dmarc@github.com; fo=1
_dmarc.wikipedia.org v=DMARC1; p=reject; rua=mailto:dmarc-rua@wikimedia.org;
Every tag and its default (RFC 7489)
| Tag | Values | Default if absent | What it controls |
|---|---|---|---|
v |
DMARC1 |
Required, must be first | Marks the record as DMARC |
p |
none, quarantine, reject |
Required, right after v |
Policy for the domain |
sp |
same as p |
Same as p |
Policy for subdomains |
rua |
list of mailto: URIs |
No aggregate reports | Where daily XML reports go |
ruf |
list of mailto: URIs |
No failure reports | Where per-message failure reports go |
adkim |
r, s |
r (relaxed) |
DKIM alignment mode |
aspf |
r, s |
r (relaxed) |
SPF alignment mode |
fo |
0, 1, d, s (colon list) |
0 |
When to send failure reports |
pct |
0 to 100 | 100 |
Share of failing mail the policy applies to |
rf |
afrf |
afrf |
Failure report format |
ri |
seconds | 86400 (one day) |
Requested gap between aggregate reports |
v and p
v=DMARC1 must be the first tag and the value is case sensitive. RFC 7489 says v and p "MUST be present and MUST appear in that order". Put p= second and you avoid the most common parse failure.
p=none asks for no action and is how monitoring works. p=quarantine asks the receiver to treat failing mail as suspicious, which usually means the spam folder. p=reject asks for rejection during the SMTP conversation.
sp, and np from the newer RFC
sp sets the policy for subdomains of the domain that publishes it. If it is absent, subdomains get p. RFC 7489 adds that sp is ignored in a record published on a subdomain; only the organisational domain's sp counts.
np comes from RFC 9091 and is now part of RFC 9989. It covers subdomains that do not exist in DNS at all, like invoice-portal.example.com invented by a phisher. v=DMARC1; p=quarantine; sp=quarantine; np=reject rejects mail from made-up names while you are still at quarantine for real ones.
rua and ruf
Both take a comma-separated list of URIs. Receivers must support mailto:. If rua is missing, RFC 7489 says receivers "MUST NOT generate aggregate feedback reports", so a record without it gives you a policy and no data. A comma that is part of an address has to be percent-encoded, since a bare comma separates entries.
Failure reports (ruf) can include headers or content of the failing message. Aggregate reports are the ones you will use day to day. To read aggregate files without sending them anywhere, open them in the DMARC report analyzer, which runs in your browser.
adkim and aspf
Relaxed alignment (r) passes when the DKIM d= domain or the SPF envelope domain shares the organisational domain with the From domain: mail.example.com aligns with example.com. Strict (s) needs an exact match. Leave both at the default unless you have a reason. Strict mode breaks every sender that signs with a subdomain.
fo, rf, ri
fo only matters when ruf is set. fo=0 asks for a report when both SPF and DKIM fail to produce an aligned pass, fo=1 when either one does, d for any DKIM signature failure and s for any SPF failure. Combine with colons: fo=1:d:s.
rf has one valid value, afrf. ri requests a reporting interval in seconds; RFC 7489 says receivers must be able to report daily and anything else is best effort, so do not count on ri=3600 producing hourly reports.
Records that look right but are not
Each of these was seen in real DNS, or breaks a rule quoted above.
p=reject; v=DMARC1; rua=mailto:dmarc@example.com
v is not first. The whole record is ignored.
v=DMARC1
No p, no rua. Under RFC 7489 section 6.6.3 the receiver applies no DMARC processing. One domain in the top 1,000 published exactly this on 19 October 2026.
v=DMARC1; p=none; sp=none; rua=mailto: dmarc@corp.example.com
A space after mailto: makes the URI invalid. A strict parser drops it, and you get no reports. We found this pattern in the top 1,000.
v=DMARC1; p=quarantine; rua=mailto:a@reports.example.net,b@reports.example.org
The second address has no mailto: scheme, so it is not a URI. One top-1,000 domain has an entry like this in a four-address rua list.
v=DMARC1; p=quarantine; pct=0; rua=mailto:dmarc@example.com
Valid syntax, but pct=0 applies the policy to no messages. RFC 9989 appendix A.6 records that some receivers took pct=0 as a cue to rewrite the From header instead. It is a testing setting, not enforcement.
example.com. TXT "v=DMARC1; p=reject"
Valid record at the wrong name. Receivers only look at _dmarc.
The external reporting authorisation record
If rua or ruf points to a mailbox outside your organisational domain, receivers check that the other domain agreed to take your reports. RFC 7489 section 7.1 describes the check, and RFC 9990 section 4 carries it forward. Without it, anyone could publish a record that floods a stranger's inbox with reports.
The receiver builds a name from three parts: your domain, _report._dmarc, and the host in the report address. If example.com publishes rua=mailto:dmarc@reports.example.net, the receiver queries:
example.com._report._dmarc.reports.example.net. TXT "v=DMARC1"
If a TXT record starting with v=DMARC1 comes back, the address is authorised. If nothing comes back, the receiver ignores that address. The owner of reports.example.net publishes this record, not you.
A reporting service that accepts reports for any domain publishes a wildcard:
*._report._dmarc.reports.example.net. TXT "v=DMARC1"
You can test a real one. Report services publish these records for each customer domain. On 19 October 2026 we found them in place for every external rua address we tested from the large senders in our scan.
If you send reports to a second domain you own, for example from brand.com to dmarc@corp-group.com, you have to publish brand.com._report._dmarc.corp-group.com yourself.
Mistakes we found in the top 1,000 domains
In our scan of the Tranco top 1,000 domains on 19 October 2026, 722 domains published a DMARC record. These patterns came up:
- No rua at all: 52 records. 26 of them are at
p=reject. The policy works, but the owner gets no reports. A few domains publish onlyv=DMARC1; p=none;, which asks for no action and no data. - pct below 100: 10 records. Values run from 0 to 50. One publishes
p=rejectwithpct=5. Two domains usepct=0. - Subdomains left open: 19 records at
p=rejectthat setsp=none. Every subdomain without its own record can then be spoofed with no policy applied. - Strict alignment: 51 records set
adkim=sand 44 setaspf=s. Fine for a parked domain. Risky for a domain whose senders sign with subdomains. - Missing p: 1 record (shown above).
- Duplicate records: none for DMARC. Three mail domains publish two SPF records instead, which RFC 7208 section 4.5 turns into a permanent error. Check yours with the SPF checker.
What RFC 9989 changes in the syntax
RFC 9989 was published as a Proposed Standard in May 2026 and obsoletes RFC 7489. For the record itself:
pct,rfandriare removed (appendix C.5.2).tis added.t=yasks receivers to apply one level below the stated policy, sop=reject; t=yis treated as quarantine. It replaces thepct=0habit.npandpsdare added.psdis for public suffix operators; leave it out on a company domain.- A record without
pis treated asp=noneinstead of being skipped, as long as it is otherwise valid.
Unknown tags must be ignored under both RFCs. A record with pct=100 or ri=86400 keeps working with new receivers, and a record with t=y does no harm at old ones. During the change, the safe pattern is a record that does not rely on pct values between 1 and 99.
Build it, then check it
Use the DMARC record generator to build a record tag by tag, publish it at _dmarc, then run the domain through the DMARC checker to confirm receivers see exactly one valid record. For the move from p=none to p=reject, follow How to implement DMARC in 5 steps. The background on alignment is in What is DMARC.