Learn

DMARC record tags reference

RFC 9989 defines eleven DMARC tags, of which only v is required: v, p, sp, np, t, adkim, aspf, rua, ruf, fo and psd. The pct, rf and ri tags from RFC 7489 are obsolete.

All tags at a glance

A DMARC record tells receivers what you want done with mail that fails DMARC and where to send reports. This table follows section 4.7 of RFC 9989, the current standard. The fourth column shows what applies when you leave a tag out.

Every DMARC tag with its values, default and status
TagMeaningAllowed valuesIf left outStatus
vVersionDMARC1RequiredActive
pPolicynone, quarantine, rejectRecommended; see below if missingActive
spPolicy for existing subdomainsnone, quarantine, rejectValue of pActive
npPolicy for non-existent subdomainsnone, quarantine, rejectValue of sp, else pActive
tTest modey, nnActive
adkimDKIM alignment moder, srActive
aspfSPF alignment moder, srActive
ruaAggregate report addressesComma-separated URIsNone: no aggregate reportsActive
rufFailure report addressesComma-separated URIsNone: no failure reportsActive
foFailure report options0, 1, d, s (colon-separated)0Active
psdPublic suffix flagy, n, uuActive
pctPercentage of failing mail0 to 100100 in RFC 7489Obsolete
rfFailure report formatafrfafrf in RFC 7489Obsolete
riAggregate report intervalSeconds86400 in RFC 7489Obsolete

Section 9.3 of RFC 9989 marks pct, rf and ri as "historic" in the IANA registry, meaning deprecated and not expected in any current implementation. Their values come from RFC 7489. See what changed in RFC 9989 for why.

How a record is written

A DMARC record is a DNS TXT record at _dmarc under the domain, so the record for example.com lives at _dmarc.example.com. Its contents are tag=value pairs separated by semicolons. A few rules apply to all of them:

  • v must come first. Spaces and tabs around = and ; are allowed, and a final semicolon is optional.
  • Unknown tags must be ignored, and a value with a syntax error is discarded in favour of the default, if the tag has one. So a typo often removes a setting silently without invalidating the record.
  • A repeated tag is more serious. DMARC uses the tag-value syntax of RFC 6376, whose section 3.2 says that if a tag name occurs more than once "the entire tag-list is invalid".
  • If a name returns more than one DMARC record, receivers discard all of them. Publish exactly one record at each name.
  • DNS can split a long TXT record into several strings. Receivers join them in order and read the result as a single string, as section 4.5 requires.

v: version

Required, and the only possible value is DMARC1, which is case sensitive. It must be the first tag. If it is not first, is absent or holds any other value, the entire record must be ignored, so v=dmarc1 means the domain has no usable record at that name.

p: policy

States how you want mail handled when it uses your domain and does not pass DMARC. It applies to the domain and to its subdomains unless sp or np says otherwise. The values:

  • none: you offer no expression of preference. This is monitoring mode.
  • quarantine: you consider such mail suspicious. It may be valid, but the failure is a significant concern.
  • reject: you consider all such failures a clear sign that the use of the domain is not valid.

RFC 9989 calls p recommended rather than required. The rule for a record without a valid p depends on rua: with at least one syntactically valid report URI, the receiver acts as if the record said p=none; without one, it applies no DMARC processing to the message. Do not rely on either. Always write p, and put it right after v: RFC 7489 requires v and then p, and Google's setup guide says these two must be listed first.

These values state a preference, not an order. Section 5.4 leaves the final handling of every message to the receiver.

sp: policy for existing subdomains

Takes the same values as p and applies only to subdomains that exist, never to the Organizational Domain itself. Without it, subdomains get p. It has no effect on a record published at a subdomain: when the From domain has its own record, the receiver takes the policy from that record's p.

np: policy for non-existent subdomains

Takes the same values as p and applies only to subdomains that do not exist. A name does not exist when a DNS query for it returns NXDOMAIN. Having no MX or A record is not enough: under RFC 9989, any record at the name means the name exists. Without np, the receiver uses sp, and without that, p.

An invalid value in sp or np has the same consequence as an invalid p: the receiver treats the whole record as p=none if it has a valid rua URI, and applies no DMARC processing if it does not. One typo in np can therefore cancel a p=reject.

t: test mode

New in RFC 9989, default n. With t=n you ask for the policy as specified. t=y is a request not to apply the policy but to apply any special handling the receiver has in place, such as rewriting the From header. You also expect failing mail to get one level below the published policy: p=quarantine; t=y means none, and p=reject; t=y means quarantine. It covers the policy in p, sp and np, does not affect reports, and has no effect on a policy of none.

What t=y means, in the RFC's words covers it in more detail, and the rollout guide shows it in use.

adkim and aspf: alignment modes

adkim sets how closely the DKIM d= domain must match the From domain, and aspf does the same for the domain SPF checked. Both take r or s and default to r.

  • r, relaxed: the two domains must have the same Organizational Domain.
  • s, strict: the two domains must be identical.

You can set them separately, for example adkim=s; aspf=r. Strict mode closes one risk, described in section 11.8: under relaxed alignment, whoever controls a subdomain's SPF or DKIM records can produce a DMARC pass for the parent domain. It also fails any service that signs or bounces with a different subdomain of yours, as DMARC alignment explained shows with examples.

rua: aggregate report addresses

A comma-separated list of URIs that should receive aggregate reports as defined in RFC 9990. Without rua, receivers must not generate aggregate reports for the domain, so this is the tag that gives you visibility. Any valid URI is allowed, but a receiver only has to support mailto: and must ignore schemes it does not support. Commas and exclamation points inside a URI must be encoded.

If an address is at a domain with a different Organizational Domain, the receiver must first verify that the other domain agreed to take the reports. For example.com sending reports to reports.example.net, that means a TXT record starting with v=DMARC1 at example.com._report._dmarc.reports.example.net. Without it, the address must be ignored.

ruf: failure report addresses

Uses the same format as rua, but asks for message-specific failure reports, which RFC 9991 describes. Without it, receivers must not generate failure reports for the domain. An address at another organization needs the same authorization record as for rua, as section 5 of RFC 9991 requires. A receiver that sends these reports must support mailto:, but section 1 of RFC 9989 says a receiver is under no obligation to send requested reports at all, so an empty ruf mailbox proves nothing.

fo: failure report options

Chooses which failures should generate a failure report. It defaults to 0 and must be ignored if the record has no ruf. Report generators may choose to follow it. Combine values with colons, for example fo=1:d, in any order, except that 0 and 1 exclude each other:

  • 0: report if all underlying authentication mechanisms fail to produce an aligned pass.
  • 1: report if any underlying mechanism fails to produce an aligned pass.
  • d: a DKIM failure report if a signature failed evaluation, regardless of alignment.
  • s: an SPF failure report if SPF failed, regardless of alignment.

psd: public suffix flag

Tells the DNS Tree Walk where the Organizational Domain is. The default is u. y is what public suffix operators publish to mark a public suffix, and n declares a domain that is not a public suffix but is the Organizational Domain for itself and its subdomains. A single record with y or n stops the walk, so a misplaced value changes alignment for every name below it.

If you run an ordinary domain, leave it out unless you delegate parts of your DNS and want a boundary between them, or a suffix above you publishes a record without psd=y. The alignment article walks through both.

Obsolete tags

These three appear in many existing records and older guides. They were defined in RFC 7489 and removed by RFC 9989, so delete them when you next edit a record.

  • pct was the percentage of failing mail the policy applied to, from 0 to 100 with a default of 100. Values other than 0 and 100 were usually not applied accurately, which is why it was removed. To test a policy, use t=y. Receivers still on RFC 7489 do not know t, which is why Patchkit's testing records carry t=y; pct=0 as a pair.
  • rf was the failure report format, with afrf as the only supported value.
  • ri was the requested interval between aggregate reports in seconds, with a default of 86400. Anything other than daily was best effort. RFC 9989 now says receivers should send aggregate reports at least daily.

One obsolete piece of syntax is not a tag: a size limit after a report address, as in mailto:dmarc@example.com!10m. Reporters should ignore it, so remove that as well.

A worked example

This record for example.com uses most tags at once. It is built to show them working together, not as a recommendation:

v=DMARC1; p=quarantine; sp=reject; np=reject; adkim=s; rua=mailto:dmarc@example.com,mailto:reports@reports.example.net; ruf=mailto:failures@example.com; fo=1

Tag by tag:

What each tag of the example record means
TagReading
v=DMARC1Identifies the record.
p=quarantineMail from example.com that fails DMARC is suspicious.
sp=rejectMail from a subdomain that exists and fails DMARC is not valid.
np=rejectSo is mail from a subdomain that does not exist.
adkim=sA DKIM signature counts only if d= is exactly the From domain.
rua=...Aggregate reports go to two addresses; the second needs the authorization record below.
ruf=...Failure reports, from receivers that send them, go to one address.
fo=1Report when any mechanism fails to produce an aligned pass.

What the record leaves out takes its default: aspf is relaxed, t is n, and psd is u. Because the second report address is at another organization, reports reach it only after reports.example.net publishes this:

example.com._report._dmarc.reports.example.net  TXT  "v=DMARC1"

Here is how a receiver picks the policy for failing mail, assuming this is the only DMARC record in the tree. example.com gets p, so quarantine. news.example.com exists but has no record, so the walk reaches this record and it gets sp, so reject. nothing.example.com returns NXDOMAIN, so it gets np, also reject. If news.example.com later publishes its own record, that record applies to it instead, and this one no longer matters for that name.

Most domains start with far less. Everything else in this record takes its default:

v=DMARC1; p=none; rua=mailto:dmarc@example.com

Section 5.1.4 of RFC 9989 describes this starting point, called monitoring mode. Read the reports it brings in, fix what fails, and only then move towards enforcement.

Checking your tags

The DMARC checker reads the record that applies to a domain and reports on its tags:

  • Errors for a missing or wrong v, a repeated tag, more than one record at a name, and invalid p, sp, np, adkim or aspf values.
  • Warnings for unknown tags and an invalid t, and when rua is missing.
  • Notes on rf and ri as removed tags, on a pct from 1 to 99, and on t=y without pct=0.
  • For rua, a check that each of the first three outside addresses has published authorization.

It does not validate fo or psd values, and it says nothing about pct=100, which changes nothing but can still be deleted. The DMARC generator writes v, p, rua and the testing tags; add np, ruf, fo or psd by hand. Once a record with your report address is live, DMARC monitoring reads the reports for you.

DMARC setup guides by service

Mailbox providers

Marketing platforms

Transactional email

Help desks

Related tools and articles

We use Google Analytics cookies only if you accept. Privacy policy