From p=none to p=reject: Moving DMARC Forward Without Losing Mail

Most domains that publish DMARC stop at p=none. The record exists, a reporting address collects
XML files nobody reads, and anyone on the internet can still send mail that claims to come from your
domain. Receivers see the record, note that you asked them to do nothing, and deliver the forgery.
Getting to p=reject is mostly bookkeeping: find every system that sends mail as your domain, make
each one authenticate properly, then tighten the policy in steps. This article walks through that
process and the places where real organizations usually get stuck.
What DMARC actually checks
DMARC builds on two older mechanisms:
- SPF lists the servers allowed to send mail for a domain. The receiver checks the connecting
IP against the SPF record of the envelope sender (the
MAIL FROM, also called the return path). - DKIM adds a cryptographic signature to the message. The receiver fetches the public key from
DNS using the signing domain (
d=) and selector (s=) in the signature header.
Neither of these looks at the From: address that people actually see. DMARC closes that gap with
alignment: a message passes DMARC only if SPF or DKIM passes and the domain it authenticated
matches the visible From: domain.
- With relaxed alignment (the default),
mail.example.comaligns withexample.combecause they share the same organizational domain. - With strict alignment (
aspf=s,adkim=s), the domains must match exactly.
Only one of the two has to align. That detail matters later: DKIM alignment is what keeps legitimate mail passing when SPF breaks along the way.
Step 1: publish p=none with reporting
Start with a record that changes nothing about delivery but tells receivers where to send reports:
_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"
p=noneasks receivers to take no action on failures.ruais the address for aggregate reports: daily XML summaries per receiving organization, listing source IPs, message counts, and the SPF, DKIM and DMARC result for each.
If the report address is on a different domain (a reporting service, for example), that domain has
to authorize it with a record like example.com._report._dmarc.reports-vendor.net TXT "v=DMARC1".
Reputable services set this up for you; if you run your own, don’t forget it, or receivers will
silently skip sending reports.
Leave ruf (forensic or failure reports) out unless you have a reason. Few large receivers send
them, and the ones that arrive can contain message content.
Major mailbox providers already expect at least this much. Since 2024, Gmail and Yahoo require bulk
senders to publish a DMARC record, and p=none satisfies that requirement. It does not protect
your domain, though; it only gives you visibility.
Step 2: read the reports and build a sender inventory
Raw aggregate reports are hard to read by hand. A parser or a reporting service turns them into a table of sending sources. Let it run for at least two to four weeks so monthly jobs (invoices, newsletters, password reminders that are rarely triggered) show up.
Sort every source into one of three groups:
- Yours and passing. Aligned DKIM or aligned SPF, nothing to do.
- Yours and failing. A real service you use that isn’t authenticating as your domain yet. This is your work list.
- Not yours. Unknown IPs sending as your domain. This is the spoofing that
p=rejectwill stop.
Typical entries in group 2:
- Marketing and newsletter platforms that send with their own return-path domain, so SPF passes for their domain but doesn’t align with yours.
- Help desks, CRMs and billing tools that send notifications “from” your address.
- Web servers and contact forms sending through local mail binaries with no DKIM.
- Forgotten SaaS someone connected years ago, still sending the odd notification.
Step 3: fix alignment, preferring DKIM
For each failing service, look for its “custom domain” or “domain authentication” setting. Almost every reputable sender supports DKIM signing with your domain, usually by asking you to publish one or two CNAME or TXT records under a selector they choose.
Prefer DKIM over SPF for alignment, for three reasons:
- Forwarding breaks SPF. When a message is forwarded, the forwarding server’s IP isn’t in your SPF record. A valid DKIM signature survives as long as the message isn’t modified.
- SPF has a hard limit of 10 DNS lookups. Every
include:for another vendor costs at least one, and nested includes add more. Exceed the limit and SPF returnspermerrorfor everyone. - Many vendors can’t align SPF at all, because the return path has to stay on their domain to process bounces.
Keep SPF tidy anyway: remove includes for services you no longer use, and end the record with ~all
or -all. Our guide to email authentication covers the SPF, DKIM
and DMARC records side by side.
For DKIM keys, use 2048-bit RSA where the provider allows it, and keep a note of which selector belongs to which service. That list makes later clean-up and key rotation much easier.
Step 4: move to quarantine
When the reports show your legitimate sources passing consistently, change the policy:
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com"
quarantine asks receivers to treat failing mail as suspicious, which in practice usually means
the spam folder. Mistakes are recoverable: a missed sender’s mail lands in junk rather than
disappearing, and someone notices.
Keep watching the reports for a few weeks. New failing sources at this stage are usually one of:
- a department that signed up for a new tool without telling IT;
- a vendor that signs with DKIM but under its own domain instead of yours;
- mail forwarded through mailing lists that rewrite the subject or add a footer, which breaks DKIM.
Mailing lists are a known limitation. Many modern list servers rewrite the From: header to the
list’s own address when the author’s domain has a strict DMARC policy, which avoids the problem.
The ARC protocol also lets intermediaries vouch for the original authentication results, and large
receivers take it into account. You can’t fix list behaviour from your side, so don’t let it hold
up the rollout.
Step 5: reject, and cover subdomains
Once quarantine has been quiet, publish the final policy:
_dmarc.example.com. TXT "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com"
Receivers that honour DMARC now refuse unauthenticated mail claiming to be from your domain. This is also a prerequisite for BIMI, which only shows your logo for domains with an enforced policy.
Two things to check at this point:
- Subdomains. Without an
sp=tag, subdomains inherit the main policy. That’s usually what you want. If one subdomain is still being cleaned up, you can give it its own_dmarcrecord with a softer policy instead of weakening the whole domain. - Keep reporting on. Reports are how you notice that a new tool started sending or that an old
DKIM key was rotated out by a vendor. A
p=rejectrecord without anyone looking at reports tends to break quietly a year later.
Domains that never send mail
Parked domains, old brand domains and redirect-only domains are easy spoofing targets, because nobody watches them. Lock them down completely:
example.net. TXT "v=spf1 -all"
_dmarc.example.net. TXT "v=DMARC1; p=reject"
example.net. MX 0 .
The SPF record says no server may send for the domain, DMARC tells receivers to reject anything that claims to, and the “null MX” (RFC 7505) says the domain doesn’t accept mail either. No selector and no inventory needed: there is nothing legitimate to break.
A practical checklist
- Publish
p=nonewithruatoday if you have nothing; it costs nothing and starts the inventory. - Give the reports a month before changing the policy.
- Fix each sender with DKIM signing under your domain; trim SPF to what you still use.
- Move to
quarantine, watch for new sources, thenreject. - Lock down every domain you own that doesn’t send mail.
- Check your public records after each change. A passive scan of your domain, like the one
PerfoMetrix runs, reads the SPF, DMARC and common DKIM selectors from public DNS and flags a
policy still sitting at
none.
The DMARC specification itself is RFC 7489, and
dmarc.org keeps an overview and resource list. Neither is required reading to
get to reject; patience with the reports is.