All articles · Web Security

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

Cover with the article title next to an envelope with a lock, in blue on a dark background

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.com aligns with example.com because 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=none asks receivers to take no action on failures.
  • rua is 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:

  1. Yours and passing. Aligned DKIM or aligned SPF, nothing to do.
  2. Yours and failing. A real service you use that isn’t authenticating as your domain yet. This is your work list.
  3. Not yours. Unknown IPs sending as your domain. This is the spoofing that p=reject will 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 returns permerror for 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 _dmarc record 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=reject record 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=none with rua today 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, then reject.
  • 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.

Tags:DMARCSPFDKIMemailDNS