What the three policies tell receivers
A DMARC record is a TXT record at _dmarc. plus your domain:
$ dig +short TXT _dmarc.example.com
"v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com"
The p= tag tells receiving mail servers what you want done with mail that claims to be from your domain but fails DMARC:
p=none: do nothing special. Deliver it, or filter it, the way you would anyway, and send me reports. This is monitoring only.p=quarantine: treat it as suspicious. In practice that usually means the spam or junk folder.p=reject: refuse it. The receiving server rejects the message during the SMTP conversation, so the sending server gets a bounce. Gmail’s rejection uses a 5.7.26 code that mentions the domain’s DMARC policy; Outlook.com uses 5.7.509.
Two points people miss.
First, the policy only touches mail that fails. Mail that passes DMARC is unaffected whatever p= says. So the real question is never “which policy is best” but “how much of my legitimate mail fails right now”. If the answer is none, reject costs you nothing. If it’s some, reject bounces that mail.
Second, it’s a request. RFC 7489 lets receivers apply their own local policy, and they do. A receiver can still deliver mail you asked to reject, or junk mail that passed. Treat DMARC as a strong signal you send, not a switch you control.
What “fails DMARC” actually means: alignment
This is where most confusion comes from. DMARC doesn’t introduce a new check. It looks at SPF and DKIM results and asks whether they are for the same domain the recipient sees in the From: header. That’s called alignment.
A message passes DMARC if at least one of these is true:
- SPF passes and is aligned: the domain in the envelope sender (the Return-Path, also called MAIL FROM) matches the From: domain.
- DKIM passes and is aligned: the
d=domain in a valid DKIM signature matches the From: domain.
Only one needs to hold. The classic failure is a newsletter or helpdesk service that sends as news@example.com but uses its own bounce domain and signs with its own DKIM key. SPF and DKIM both pass, for the service’s domain, and DMARC still fails. You can see it in the receiving side’s Authentication-Results header (Gmail’s format shown):
Authentication-Results: mx.google.com;
dkim=pass header.i=@esp-mailer.example header.s=k1;
spf=pass (google.com: domain of bounces+8812@esp-mailer.example designates 198.51.100.23 as permitted sender) smtp.mailfrom=bounces+8812@esp-mailer.example;
dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=example.com
The fix is on the service’s side, in its domain settings: most services let you set up DKIM signing with your own domain (they give you CNAME or TXT records to add under _domainkey.example.com) and a custom bounce domain such as bounce.example.com. DKIM alignment is the one to get right. SPF breaks whenever mail is forwarded, because the forwarding server’s IP isn’t in your SPF record. DKIM survives forwarding as long as nobody modifies the signed content; mailing lists that rewrite the subject or append a footer are the usual exception.
Relaxed vs strict alignment
adkim= and aspf= control how closely the domains must match. Both default to r (relaxed).
- Relaxed: the organizational domains must match.
bounce.example.comaligns withexample.com. - Strict (
s): the domains must be identical.bounce.example.comdoes not align withexample.com.
Keep relaxed unless you have a concrete reason. Strict alignment breaks the very common setup where a service uses a subdomain of yours for bounces or signing. What it protects against is a subdomain you’ve handed to someone else (a vendor who controls promo.example.com’s DNS, say), which most organisations either don’t have or can handle with that subdomain’s own DMARC record.
The other tags that matter
| Tag | What it does | Notes |
|---|---|---|
rua=mailto:… | Where aggregate reports go | The data you need for the whole rollout. Set it from day one |
ruf=mailto:… | Where per-message failure reports go | Many large mailbox providers don’t send these at all, for privacy reasons. Optional |
pct= | Percentage of failing mail the policy applies to | Default 100. Mail outside the sample gets the next lower policy: reject becomes quarantine, quarantine becomes none |
sp= | Policy for subdomains | If absent, subdomains inherit p=. A subdomain with its own _dmarc record uses that record instead |
adkim=, aspf= | Alignment mode for DKIM and SPF | r (default) or s |
fo= | When to generate failure reports | Only matters with ruf. fo=1 asks for a report when either SPF or DKIM fails |
A few rules that trip people up:
v=DMARC1must come first in the record.- Publish one DMARC record. If a receiver finds two TXT records starting with
v=DMARC1at_dmarc.example.com, it applies no DMARC at all. - If
ruapoints to a mailbox in a different domain, that domain has to agree to receive the reports, with a TXT record likeexample.com._report._dmarc.reports.example.netcontainingv=DMARC1. Hosted report services set this up for you. If you send reports to your own other domain, you have to add it yourself, or receivers will skip the address.
Reading aggregate reports before you move
Aggregate reports are XML files, usually zipped or gzipped and attached to an email, typically one per receiving organisation per day. Each record row says: from this IP, this many messages claimed to be from your domain, here’s how SPF and DKIM came out.
<record>
<row>
<source_ip>198.51.100.23</source_ip>
<count>412</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>fail</dkim>
<spf>fail</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>example.com</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>esp-mailer.example</domain>
<selector>k1</selector>
<result>pass</result>
</dkim>
<spf>
<domain>esp-mailer.example</domain>
<result>pass</result>
</spf>
</auth_results>
</record>
Read it as two layers. auth_results shows raw SPF and DKIM: both passed. policy_evaluated shows the DMARC view, which only counts aligned results: both failed, because the domain was esp-mailer.example, not example.com. disposition is what the receiver did, none here because the policy was p=none. Under reject, these 412 messages would have bounced. This is the same service as in the header example above, and it’s exactly what the reports are for.
Raw XML gets unreadable quickly. Use a report service or an open-source parser such as parsedmarc to aggregate them, then sort every sending source into one of three groups:
- Yours, passing with alignment. Your main mail platform, usually. Nothing to do.
- Yours, failing. A CRM, billing system, ticketing tool, survey tool, a printer that emails scans, a web server sending password resets. Each one needs aligned DKIM (preferred) or aligned SPF before you enforce.
- Not yours. Spoofing, or forwarding. Forwarded mail typically shows SPF failing but DKIM passing aligned, so it still passes DMARC. Spoofing fails both, and that’s the mail you want quarantine and reject to stop.
You’re ready to move when group 2 is empty for a full cycle of your business, including senders that only send monthly or quarterly. Don’t judge by total pass rate. A 99% pass rate where the 1% is your payroll notices is not ready.
A rollout that doesn’t lose mail
1. Publish p=none with rua. Check that the record parses and that SPF and DKIM are found with the email check.
v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com
2. Fix every legitimate source. Turn on custom-domain DKIM in each service. Add services to SPF only where they need it, and watch the 10-lookup limit while you do (SPF PermError guide). If a DKIM signature fails rather than mis-aligns, the DKIM failure guide covers why.
3. Move to p=quarantine. If you want a gradual ramp, use pct: p=quarantine; pct=25, then 50, then 100, watching reports and your helpdesk at each step. Treat pct as a rough dial rather than an exact percentage; how precisely each receiver samples is up to the receiver.
4. Move to p=reject. Keep rua forever. New services get added by other teams without telling you, and the reports are how you find out.
During the rollout, keep the TTL on the _dmarc record modest (an hour is reasonable). If something legitimate starts bouncing, you want a rollback to quarantine or none to reach receivers quickly. Then fix that sender and step up again.
Subdomains and domains that never send mail
sp= lets you lock down subdomains separately. If nothing sends from subdomains, sp=reject can go in early, even while p= is still at none. If a subdomain does send (say news.example.com for a newsletter service), give it its own _dmarc.news.example.com record so its rollout doesn’t hold up the main domain.
For domains that never send mail at all, such as parked domains and defensive registrations, skip the staging. Publish reject from day one, along with an SPF record that allows nothing and a null MX (RFC 7505) that says the domain receives no mail:
parked-example.com. IN MX 0 .
parked-example.com. IN TXT "v=spf1 -all"
_dmarc.parked-example.com. IN TXT "v=DMARC1; p=reject"
Why scanners flag p=none
“DMARC quarantine/reject policy not enabled” and similar findings from security scanners and vendor questionnaires all mean the same thing: your record exists but is at p=none, or there is no record. They’re right that p=none doesn’t stop anyone from sending mail as your domain.
p=none is still a legitimate place to be for a while. Gmail and Yahoo’s bulk-sender requirements, in force since February 2024, ask for a DMARC record and accept p=none. But none is meant as a stage, not a destination. BIMI, the standard for showing your logo in inboxes, requires an enforced policy, and so do most of the scanners and questionnaires that will keep asking.
If you’re answering a questionnaire mid-rollout, say so: current policy, target policy, and when you expect to get there. That’s a better answer than flipping to reject to make the finding go away and finding out from customers which systems you forgot.
Checking where you are now
dig +short TXT _dmarc.example.com
dig +short TXT k1._domainkey.example.com # replace k1 with your DKIM selector
The email check shows SPF, DKIM and DMARC for a domain together, including the current policy, and the DNS lookup shows the exact TXT record as published, which helps when a dashboard shows one thing and receivers see another. For the full picture of where SPF, DKIM and DMARC fit together, see the email deliverability guide.
Check your own domain now
Free, no sign-up. Runs the exact check this guide describes and shows what to fix.