How to configure DMARC correctly
A step-by-step DMARC rollout from p=none to p=reject, updated for RFC 9989: reports, alignment, subdomain policies and the mistakes to avoid.
By Exmoor Software6 min read
DMARC tells receiving mail servers what to do with messages that claim to come from your domain but fail authentication, and asks them to send you reports about what they see. Done well, it stops direct spoofing of your domain. Done hastily, it can block your own invoices.
In May 2026 the IETF published DMARC as a proposed standard in three documents — RFC 9989 (the protocol), RFC 9990 (aggregate reports) and RFC 9991 (failure reports) — replacing RFC 7489 from 2015. Existing records stay valid; a few tags changed. This guide follows the new specification and points out where older receivers behave differently.
What DMARC checks
A message passes DMARC when at least one of these is true:
- SPF passes for the envelope sender domain, and that domain is aligned with the domain in the From header;
- a DKIM signature verifies, and its signing domain (
d=) is aligned with the From domain.
“Aligned” means the domains match. In the default relaxed mode, the organizational domains must match: mail.example.com aligns with example.com. In strict mode they must be identical.
This is the important part: SPF and DKIM can both pass for some domain while DMARC still fails, because neither of them is your domain. That happens whenever an email service sends with its own bounce address and signs with its own key. See SPF vs DKIM vs DMARC for a walkthrough.
Before you publish anything
Make a list of everything that sends email with your domain in the From address:
- your mailbox provider (Google Workspace, Microsoft 365, …);
- newsletter and marketing tools;
- transactional email (password resets, order confirmations);
- your web shop, CRM, helpdesk, invoicing and HR systems;
- servers, printers or scanners that email reports.
For each one, set up DKIM signing with your own domain (most services call this “custom domain authentication” and give you CNAME records to publish), and make sure it is covered by your SPF record. You will miss some — that is what the reports in the next step are for.
Step 1: publish a monitoring policy
Publish a TXT record at _dmarc. in front of your domain:
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"
v=DMARC1must come first and is case-sensitive.p=noneasks receivers to change nothing; failing mail is delivered as before.rua=is where receivers send daily aggregate reports. Without it you learn nothing.
p=none already satisfies the minimum Gmail, Yahoo and Outlook.com expect from bulk senders. It does not protect the domain.
Step 2: read the reports and fix what fails
Aggregate reports are XML files listing, per sending IP, how many messages arrived and whether SPF, DKIM and DMARC passed. They are hard to read by hand; a reporting service or an open-source parser turns them into a list of sources. To look at a single report right away, open it in the DMARC report analyzer.
Work through every source that sends legitimate mail but fails DMARC:
- An email service that passes SPF and DKIM for its own domain — enable custom DKIM with your domain, or a custom return-path (bounce) domain under your domain.
- A system that sends directly — add its IP addresses to SPF, or route it through a service that signs with DKIM.
- Forwarded mail and mailing lists — forwarding breaks SPF, and lists that modify the subject or add footers break DKIM. Large receivers use ARC (RFC 8617) to recognize trusted intermediaries; you can’t fix this from your side, and with DKIM on all your mail most of it resolves itself.
Sources you don’t recognize are typically spoofing attempts — exactly what an enforcing policy will stop.
Give this phase a few weeks, ideally covering a full billing cycle so monthly senders show up.
Step 3: enforce gradually
When the reports show your legitimate mail passing, move to quarantine:
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com"
Most receivers then deliver failing mail to the spam folder. After another quiet period, move to reject:
_dmarc.example.com. TXT "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com"
Testing mode. RFC 9989 adds t=y, which asks receivers to apply one level less than the stated policy (quarantine becomes none, reject becomes quarantine) while you watch the reports. Remove it when you are confident.
Subdomains
A record on example.com also covers its subdomains, with three policies:
| Tag | Applies to | Default |
|---|---|---|
p | the domain itself (and subdomains, unless overridden) | none (always set it explicitly) |
sp | subdomains that exist, such as shop.example.com | value of p |
np | subdomains that don’t exist, such as invoice-dept.example.com | value of sp, then p |
Phishers love made-up subdomains, so np=reject is a sensible addition even while p is still quarantine. A subdomain can also publish its own _dmarc record when it needs a different policy.
The complete tag list
| Tag | Values | Notes |
|---|---|---|
v | DMARC1 | Required, first, case-sensitive |
p | none, quarantine, reject | Policy for the domain; recommended, treated as none if missing and rua is valid |
sp | same as p | Existing subdomains |
np | same as p | Non-existent subdomains (new in RFC 9989) |
t | y, n (default) | Testing mode (new) |
rua | mailto: URIs, comma-separated | Aggregate reports |
ruf | mailto: URIs | Failure reports; rarely sent, may contain message content |
fo | 0, 1, d, s | Failure report options; only with ruf |
adkim, aspf | r (default), s | Relaxed or strict alignment |
psd | y, n, u (default) | For public suffix operators (new) |
pct, rf, ri | — | Removed in RFC 9989 |
Tag names are case-sensitive: P=reject is not the policy tag and is ignored.
How receivers find your record
Receivers first look for _dmarc.<From domain>. If there is none, RFC 9989 has them walk up the DNS tree — for mail from news.mail.example.com they query _dmarc.mail.example.com, then _dmarc.example.com, then _dmarc.com, never more than eight queries in total — to find the organizational domain’s record. RFC 7489 used the Public Suffix List for the same purpose. For ordinary domains both methods agree; if you run a complex multi-level structure, publish explicit records for the domains you send from.
Common mistakes
- The record ends up at
_dmarc.example.com.example.com. Many DNS panels append the domain to the name you type. Enter just_dmarc. v=dmarc1in lowercase, or the version not first — the record is ignored.- Two DMARC records — receivers discard both.
- A report address on another domain without authorization — reports silently never arrive.
- Jumping to
p=rejecton day one — legitimate mail from a forgotten system is rejected. - Assuming the record alone protects you — with
p=none, spoofed mail is still delivered.
Check your setup
Run the DMARC checker to see which record applies, what receivers will do with failing mail and whether your report addresses are authorized. Then confirm alignment on a real message: send one to a Gmail or Outlook mailbox and paste its headers into the email header analyzer — look for dmarc=pass.