DMARC record reference
Reference for every DMARC TXT record tag in RFC 9989 (DMARCbis): v=, p=, sp=, np=, t=, psd=, rua=, ruf=, adkim=, aspf=, fo=, plus the removed pct=, rf=, and ri= tags.
A DMARC record is a TXT record published at _dmarc.yourdomain.com. It tells receivers what policy you want applied to mail that fails DMARC, where to send reports, and how strictly to evaluate alignment. This page covers every tag defined in RFC 9989 (DMARCbis, May 2026), which obsoletes RFC 7489. It also covers the three tags RFC 9989 removed.
A minimal valid record looks like:
_dmarc.yourdomain.com TXT "v=DMARC1; p=none; rua=mailto:reports@yourdomain.com"Tag reference
RFC 9989 §4.7 defines these tags: v, p, sp, np, t, psd, rua, ruf, adkim, aspf, and fo. Keyword values such as reject, y, or s are not case-sensitive. The version value DMARC1 is.
v= (version)
Required. Must be DMARC1, and it must be the first tag in the record. DMARCbis did not change the version: there is no DMARC2.
v=DMARC1If v is missing, isn't first, or isn't exactly DMARC1, receivers ignore the entire record (RFC 9989 §4.7).
p= (policy)
Recommended. Tells receivers how you want mail that fails DMARC handled.
| Value | What you're asking for |
|---|---|
none | No handling preference. Deliver as normal and send reports (Monitoring Mode) |
quarantine | Treat failing mail as suspicious, usually by filing it to spam or junk |
reject | Treat failures as a clear sign the use of your domain is not valid, usually by refusing the message |
RFC 7489 made p required. RFC 9989 makes it RECOMMENDED. If a record has no valid p tag, receivers treat it as p=none only if the record also has a rua tag with at least one valid reporting URI. Without that, the receiver applies no DMARC processing at all (RFC 9989 §4.10.1). Always publish p explicitly.
The policy is a request, not a command. RFC 9989 §7.4 says receivers MUST NOT reject mail solely because of p=reject. In the absence of other knowledge, receivers treat such failing mail as if the policy were quarantine. The same section says domains publishing p=reject MUST NOT rely solely on SPF and MUST sign their mail with valid DKIM.
Start with p=none while you're monitoring. See when to move from p=none to enforcement for the readiness checklist.
sp= (subdomain policy)
Optional. Policy for existing subdomains of your organizational domain. It takes the same values as p. If omitted, subdomains get the p= policy.
sp=noneUse it when you want different enforcement on subdomains than on the apex. A common pattern: p=reject on yourdomain.com with sp=quarantine while you finish auditing subdomain senders.
sp only has an effect on the organizational domain's record. RFC 9989 §4.7 notes that it is ignored on records published on subdomains, because of how policy discovery works.
np= (non-existent subdomain policy)
Optional. Policy for subdomains that don't exist in DNS (queries return NXDOMAIN). It takes the same values as p.
np=rejectnp was introduced in RFC 9091 and is now part of the core spec. It applies only to non-existent subdomains, not to existing subdomains or to the domain itself. If np is absent, receivers fall back to sp, and then to p if sp is also absent (RFC 9989 §4.7).
Spoofers often invent subdomains like billing.yourdomain.com that were never created. np=reject asks receivers to treat that mail as strictly as possible, even while sp stays softer for your real subdomains.
t= (testing mode)
Optional. New in RFC 9989. y or n. Default is n.
t=yt=y tells receivers you are testing your policy and expect failing mail to be handled one level below the policy you published:
| Published policy | With t=y, receivers apply |
|---|---|
p=reject | quarantine |
p=quarantine | none |
p=none | none (t has no effect) |
The same step-down applies to sp and np when either is the policy in effect. t=y also invites whoever is checking DMARC, whether a mailbox provider or an intermediary, to apply any special handling it has in place, such as rewriting the From header. t does not change reporting: you get the same aggregate reports either way (RFC 9989 §4.7).
t=y replaces the useful part of the old pct=0. RFC 7489 receivers don't recognize t, so during the transition publish it alongside pct=0. See The t=y; pct=0 transition pair below.
psd= (public suffix domain flag)
Optional. New in RFC 9989. y, n, or u. Default is u.
| Value | Meaning |
|---|---|
y | This domain is a public suffix domain (for example, a TLD or a registry-controlled suffix) |
n | This domain is not a public suffix, and it is the organizational domain for itself and its subdomains |
u | Not a public suffix; may or may not be an organizational domain. Receivers work it out with the DNS tree walk |
psd=y is for public suffix operators, such as TLD registries. Most domain owners should leave psd out. psd=n is useful only if you want to pin the organizational domain boundary at your own domain (RFC 9989 §4.7, §4.10.2).
RFC 9989 replaces the Public Suffix List with a DNS tree walk for finding organizational domains. The walk queries _dmarc records up the DNS tree, capped at eight queries (§4.10). If you send from an Author Domain with more than eight labels and want a specific policy to apply, publish a DMARC record at that exact name (§5.1.8).
rua= (aggregate report address)
Optional but strongly recommended. Where receivers send aggregate reports. One or more URIs, comma-separated. Receivers that send reports must support mailto:.
rua=mailto:reports@yourdomain.com
rua=mailto:d-abc123@in.dmarcdrift.com
rua=mailto:reports@yourdomain.com,mailto:d-abc123@in.dmarcdrift.comWithout rua=, receivers MUST NOT send you aggregate reports (RFC 9989 §4.7), so you get no data about who is sending as your domain. RFC 9989 §5.3.8 says receivers SHOULD send aggregate reports at least once every 24 hours. The report format is defined in RFC 9990.
To add DMARCdrift without removing an existing rua= address, append it with a comma. Receivers send reports to every listed address.
The old size-limit suffix on report URIs (mailto:reports@yourdomain.com!10m) is obsolete. Receivers should ignore it (RFC 9989 §4.8, Appendix C.4).
ruf= (failure report address)
Optional. Where to send failure reports (sometimes called forensic reports) about individual messages that fail DMARC. The format is defined in RFC 9991.
ruf=mailto:failures@yourdomain.comruf is still a current tag in RFC 9989. In practice, most large mailbox providers rarely send failure reports, so don't rely on them as your main source of data. DMARCdrift ingests failure reports sent to your DMARCdrift address, alongside aggregate reports. See DMARC failure reports (ruf) for what they contain.
adkim= (DKIM alignment mode)
Optional. How strictly the DKIM signing domain must match your From domain.
| Value | Behavior |
|---|---|
r | Relaxed: organizational domain match (default) |
s | Strict: exact domain match required |
Default is r (relaxed) if omitted. See relaxed vs strict alignment for when strict makes sense.
aspf= (SPF alignment mode)
Optional. How strictly the SPF envelope sender domain must match your From domain.
| Value | Behavior |
|---|---|
r | Relaxed: organizational domain match (default) |
s | Strict: exact domain match required |
Default is r (relaxed) if omitted. Mirrors adkim= but applies to SPF.
fo= (failure reporting options)
Optional. Controls what triggers a failure report. Default is 0. Receivers MUST ignore fo if the record has no ruf tag.
| Value | Behavior |
|---|---|
0 | Report if all underlying mechanisms fail to produce an aligned pass (default) |
1 | Report if any underlying mechanism fails to produce an aligned pass |
d | Report a DKIM failure if a signature failed evaluation, regardless of alignment |
s | Report an SPF failure if SPF evaluation failed, regardless of alignment |
Combine values with colons, for example fo=1:d. RFC 9989 tightened the grammar (§4.8):
0and1are mutually exclusive, sofo=0:1is now invalid.dandsmay each appear at most once.
An invalid fo value is discarded and the default 0 applies. Receivers may choose whether to follow the options you request (§4.7).
A complete example
_dmarc.yourdomain.com TXT "v=DMARC1; p=reject; sp=quarantine; np=reject; adkim=r; aspf=r; rua=mailto:d-abc123@in.dmarcdrift.com"This record requests reject for the apex domain, quarantine for existing subdomains, and reject for subdomains that don't exist. It uses relaxed alignment for both DKIM and SPF and sends aggregate reports to DMARCdrift.
Removed in DMARCbis
RFC 9989 removed three tags that RFC 7489 defined. They are listed as "historic" in the IANA DMARC tag registry (RFC 9989 §9.3, Appendix C.5.2). DMARCbis receivers don't process them. Receivers that still implement RFC 7489 may.
pct= (percentage)
In RFC 7489, pct (0 to 100, default 100) asked receivers to apply your policy to only that percentage of failing mail. Under RFC 7489 §6.6.4, the share not selected dropped one level: mail outside the sample was quarantined under p=reject, and handled normally under p=quarantine.
RFC 9989 Appendix A.6 explains the removal. pct "was usually not accurately applied, unless the value specified was either 0 or 100", and other values behaved differently from one receiver to the next. pct=0 turned out to be useful, because some intermediaries and mailbox providers treated it as a signal to rewrite the From header. RFC 9989 keeps that behavior through the new t tag.
If you use pct below 100 to ramp up enforcement, move between policy levels instead, and use t=y for a test step.
rf= (report format)
In RFC 7489, rf requested a format for failure reports (default afrf). RFC 9989 removed it (Appendix C.5.2), and the failure report format is now defined in RFC 9991. Delete rf from your record.
ri= (report interval)
In RFC 7489, ri requested an interval between aggregate reports in seconds (default 86400), and anything other than daily was best effort. RFC 9989 removed it (Appendix C.5.2) and instead says receivers SHOULD send aggregate reports at least once every 24 hours (§5.3.8). Delete ri from your record.
The t=y; pct=0 transition pair
RFC 9989 describes t=y and t=n as "meant to be analogous" to pct=0 and pct=100 (Appendix A.6). It does not say a receiver should treat pct=0 as t=y. During the transition you'll meet both kinds of receiver:
- RFC 7489 receivers ignore
t, because it is an unknown tag to them, but they honorpct. - RFC 9989 receivers ignore
pctbut honort.
To get test-mode handling from both, publish the two tags together:
_dmarc.yourdomain.com TXT "v=DMARC1; p=quarantine; t=y; pct=0; rua=mailto:d-abc123@in.dmarcdrift.com"Both kinds of receiver end up one level below the published policy. An RFC 7489 receiver applies pct=0 under §6.6.4, and an RFC 9989 receiver applies t=y under §4.7. This is our reading of the two specs. Neither RFC states it as a combined rule. When you're ready to enforce, remove both tags together.
Don't publish pct=0 on its own. An RFC 9989 receiver ignores it and applies your full policy.
Unknown tags and syntax errors
Receivers ignore tags they don't recognize. If a tag has an invalid value, the receiver discards it and uses the default, or ignores the tag if there is no default (RFC 9989 §4.7, §4.8). A typo like t=yes doesn't turn testing on. It falls back to the default t=n.
See also: When to move from p=none to enforcement: the readiness checklist before changing your policy. Relaxed vs strict DMARC alignment: when adkim=s or aspf=s makes sense. RFC 9989: what actually changed: the DMARCbis changes in one place.