DMARC record
Tells receivers what to do when a message fails aligned SPF and DKIM, and where to send reports.
Written and maintained by Ben Ennis
Last reviewed July 27, 2026 · How we verify this
Zone-file example
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"Typical uses
- Starting at p=none to collect aggregate reports before enforcing anything
- Moving to p=quarantine and then p=reject once the reports look clean
- Discovering forgotten senders through rua aggregate feedback
- Protecting the visible From: domain, which SPF and DKIM alone do not
When it breaks, check
- Alignment is the part people miss: SPF or DKIM passing is not enough on its own
- The record lives at _dmarc.example.com, and only one v=DMARC1 record may exist there
- Subdomains inherit the organisational policy unless sp= says otherwise
- Sending rua to another domain needs an authorising record published in that domain
What the DMARC record does
The idea DMARC adds is alignment, and it is the part almost everyone misses.
SPF authenticates the SMTP envelope sender and DKIM authenticates the signing domain in
d=; neither has any necessary relationship to the From: header.
Someone can send mail passing SPF for a domain they own while displaying your domain in
From:. DMARC requires that a passing SPF or DKIM result use a domain matching
the From: domain — strictly, or relaxed to the organisational domain — and
treats an unaligned pass as no pass at all.
One aligned pass is enough. DKIM alignment is the one that survives forwarding, so lists and relays make it the more dependable of the two.
TXT record syntax
The record is a TXT string of semicolon-separated tags at
_dmarc.<domain>. v=DMARC1 and p= are
mandatory and must appear first, p= being none,
quarantine, or reject. rua= and ruf=
give mailto URIs for aggregate and failure reports, pct= applies the policy
to a sample, sp= overrides it for subdomains, and adkim= and
aspf= switch each alignment test between relaxed, the default, and strict.
; reporting only — always start here
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
; enforcing, with a stricter policy for subdomains
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=quarantine; sp=reject; adkim=s;
rua=mailto:dmarc@example.com; pct=100"
; reports going off-domain need this record in the RECEIVING zone
example.com._report._dmarc.reports.vendor.net. IN TXT "v=DMARC1"
Common uses
The deployment path is fixed and worth following exactly. Publish
p=none with an rua address and change nothing else; aggregate
reports will name every source sending as your domain, including the marketing platform
and the ancient monitoring box nobody remembered. Fix or authorise each one, then move to
p=quarantine, then p=reject. Jumping straight to enforcement is
how organisations find their own invoices in the spam folder.
Troubleshooting
When a message fails DMARC despite passing authentication, the answer is
almost always alignment. Read the Authentication-Results header, compare the
SPF envelope domain and the DKIM d= against the From: domain,
and check whether you set adkim=s or aspf=s, which forbid the
subdomain matching that relaxed mode allows.
Reporting addresses are the other trap. Pointing rua at a mailbox in a domain
you do not control requires that domain to publish a record authorising yours, per
RFC 7489 §7.1. Without it, conforming receivers send nothing and your
dashboard stays empty for a reason that never surfaces as an error.
# the policy record
dig _dmarc.example.com TXT +short
# subdomains inherit unless sp= or their own record says otherwise
dig _dmarc.mail.example.com TXT +short
# off-domain reporting must be authorised in the receiving zone
dig example.com._report._dmarc.reports.vendor.net TXT +short
ruf= reports need fo= to say what counts as a failure worth reporting
Everything above concerns rua, the aggregate reports that drive the
none-to-reject rollout. DMARC has a second, separate report type, per-message failure
reports sent to ruf=, and it is governed by a tag this page has not
mentioned yet: fo=. RFC 7489 §6.3 defines four values, and the
tag’s content is explicitly meaningless without ruf present — “MUST be
ignored if a ‘ruf’ tag is not also specified.” The default, fo=0, only
generates a failure report when every underlying mechanism fails to produce an aligned
pass; fo=1 loosens that to any mechanism failing alignment, even if another
one passed. fo=d and fo=s are narrower still and diagnostic
rather than policy-driven: d reports a DKIM signature that failed
evaluation regardless of alignment, and s does the same for an SPF failure,
which is useful for debugging a sender’s authentication independently of whether DMARC
itself would have passed the message.
In practice ruf sees far less real deployment than rua, because
per-message failure reports can contain enough of the original message to be a privacy
and volume concern for receivers, and many large providers do not send them regardless of
what fo= requests — the RFC itself only says report generators “MAY choose to
adhere” to the requested options, not that they must. Set fo=1 if you add
ruf at all, since the default fo=0 silently discards the
partial-failure cases you are usually trying to catch, but do not expect it to replace
rua as your primary visibility source.
The defining RFC
DMARC is RFC 7489. Note its status: Informational, published through the Independent Submission stream rather than the IETF standards track, despite near-universal deployment. Identifier alignment is section 3.1, the tag grammar section 6.3, and external destination verification section 7.1. A revision is in progress in the IETF DMARC working group as draft-ietf-dmarc-dmarcbis; it has not been published as an RFC, so cite the draft, never a number. Query a policy with the DNS lookup tool.
Reference and tooling
Every record type and its assigned numeric value is listed in theIANA DNS Parameters registry. To query a live zone from the browser, use theDNS lookup tool. If the record you are chasing is TLS-related, the TLS inspector andCertificate Transparency lookup are usually the next two stops.