DMARC from p=none to p=reject: step by step

· 5 min read

Most domains that have a DMARC record at all have been sitting on p=none for years. That is a monitoring mode, not protection. The road to p=reject is not rocket science, but it needs reports, patience and a fixed order of steps.

Why p=none protects nothing

DMARC as defined in RFC 7489 does two things: it checks whether SPF or DKIM match the sender domain in the From header (alignment), and it tells the receiver what to do with messages that fail this check. With p=none the instruction is: do nothing, just report. Forged messages are delivered exactly as they would be without DMARC.

p=none still has a purpose. Through the rua address you receive aggregate reports from all major receivers and see who is sending on behalf of the domain. Without this phase you do not know which systems you would cut off with p=reject.

_dmarc.example.com.  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@example.com"

Phase 1: Find all senders

Leave p=none in place for at least two to four weeks and evaluate the reports. Every report lists source IPs with the number of messages and the SPF and DKIM results including alignment. Sort the sources into three groups: your own systems with pass, your own systems with fail, and strangers. The middle group is your to do list.

Typical surprises are the web server with the contact forms, the invoicing tool used by accounting, a newsletter service the client signed up for themselves, and employees forwarding mail to private mailboxes. Monthly senders such as payroll only show up after four weeks, hence the minimum duration.

Phase 2: Establish alignment

A DMARC pass needs more than an SPF or DKIM pass, it needs an aligned pass. For SPF the envelope from domain (Return-Path) must match the From domain, for DKIM the d= domain of the signature must. In the default relaxed mode the same organisational domain is enough, so newsletter.example.com aligns with example.com. In strict mode the domains must match exactly.

For every sender with fail there are two options: either the service sends with a Return-Path on your domain (SPF alignment), or it signs with DKIM under your domain (DKIM alignment). With most providers DKIM is the more reliable path because it survives forwarding. Leave strict alone unless you have a concrete reason for it.

  • aspf=r and adkim=r (relaxed) are the default and right for almost every domain
  • A sender only needs one of the two: SPF alignment or DKIM alignment
  • Services without a custom domain cannot align; then the service has to be replaced or moved to a subdomain that is exempt from the DMARC policy

Phase 3: Introduce p=quarantine with pct=

Once the reports show that all known senders pass, switch to p=quarantine. The pct= parameter lets you apply the policy to only a percentage of failing messages. Start with a low value, watch the reports for a week and increase step by step. Messages not covered by the percentage are handled with the next lower policy, so with quarantine that means none.

Quarantine means the receiver should treat the message as suspicious, in practice usually the spam folder. That is reversible if you did miss a sender after all, which makes it the right intermediate step.

Week 1:
v=DMARC1; p=quarantine; pct=10; rua=mailto:dmarc@example.com

Week 2:
v=DMARC1; p=quarantine; pct=50; rua=mailto:dmarc@example.com

Week 3:
v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com

Phase 4: p=reject and subdomains

After one to two weeks of full quarantine without new outliers, switch to p=reject. Receivers then refuse failing messages at delivery time. Here too you can use pct= to ramp up, in which case uncovered messages are handled with quarantine.

The sp= tag sets the policy for subdomains that have no DMARC record of their own. Without sp=, the main policy applies to subdomains as well. Use sp= if you deliberately want to treat a subdomain more leniently, for example while a newsletter tool is still being migrated. Conversely, sp=reject can make sense while the main domain is still on quarantine, because attackers like to forge non existent subdomains.

Target state:
_dmarc.example.com.  TXT  "v=DMARC1; p=reject; sp=reject; adkim=r; aspf=r; rua=mailto:dmarc@example.com"

What can break at reject

Forwarding is the biggest problem. A receiver that forwards mail to another address changes the sending host, which breaks SPF. DKIM survives plain forwarding, but not mailing lists that add subject prefixes or footers. Such messages are refused at p=reject although they are legitimate.

ARC (Authenticated Received Chain) is meant to solve this by letting the forwarding server pass on the original authentication results in signed form. Large providers evaluate ARC, many smaller ones do not. You cannot influence that, only plan for it: tell the client that mail through mailing lists and forwarding chains can be lost at reject, and make sure all of your own senders sign with DKIM.

Timeline and rollback

For a typical client domain with three to five senders you need four to eight weeks. The timeline cannot be shortened at will because you have to wait for reports, which arrive daily. What can be shortened is the reaction time to outliers.

A rollback is possible at any time: set p= back to the previous value and the new policy takes effect within the TTL. Messages that were already refused do not come back, though. That is why you go through quarantine and pct= rather than jumping from none to reject.

  1. Weeks 1 to 4: p=none with rua, identify all senders, establish alignment for each of them.
  2. Weeks 4 to 6: p=quarantine with pct=10, then 50, then 100. Check the reports after every step.
  3. Weeks 6 to 8: p=reject, first with pct=, then in full. Set sp= for subdomains.
  4. Afterwards: keep watching the reports, because new services are added all the time.

Frequently asked questions

Is p=quarantine enough permanently?
It is much better than none, but the spam folder is not a safe place. Users pull messages out of it, and some receivers treat quarantine leniently. If a domain is used for invoices or customer communication, reject is the goal.
Do I need a separate DMARC record for every subdomain?
No. Without its own record, the policy of the organisational domain applies, controlled by sp=. A dedicated record on the subdomain is only needed if you want different rules or separate report addresses there.
What do I do with a service that cannot align?
Either let it send from a subdomain that you exempt via sp=none or a dedicated record, or replace the service. Postponing reject to accommodate one service on the main domain is not a solution.
Check now

Free DMARC record check and lookup: policy (none, quarantine, reject), pct, reporting addresses and syntax errors. With recommendations for moving to p=reject.

Moving to p=reject is only the beginning, because every new service can put delivery at risk again. DomainWarn monitors the DMARC, SPF and DKIM records of your client domains and reports every change immediately.

Monitor this domain continuously14-day free trial, no credit card.

More guides