Moving DMARC from p=none to p=reject Without Breaking Your Own Mail
Most domains that have DMARC have p=none, and most of them have had it for years. The record was added to satisfy a checklist, the reports go to an address nobody reads, and the domain is exactly as spoofable as it was before. Moving to p=reject is not hard, but it does need to be done in order, and the order is what this post is about.
Why none is not a policy
p=none tells receivers to do nothing when DMARC fails. It exists so you can turn on reporting without risk. That was the intent. In practice it becomes permanent, and a domain at none has no protection against spoofing, does not qualify for BIMI, and — under the 2026 RFC 9989 rules — is treated by some receivers as a signal of low sender care. It does satisfy the Gmail and Yahoo bulk-sender requirement, which is why so many domains stop there.
Stage 1: publish none with reporting
If you have no record, start with v=DMARC1; p=none; rua=mailto:dmarc@yourdomain. The rua address is the point — it receives daily XML reports from every major receiver listing each source that sent mail claiming your domain, the volume, and whether SPF and DKIM passed and aligned. Use a dedicated mailbox or a reporting service; the raw XML is unreadable by eye but the report parser turns a day's worth into a table in seconds. Give it two to four weeks so that monthly senders show up.
Stage 2: fix every legitimate source
Sort the report by volume. For each source that is yours — the mail provider, the CRM, the helpdesk, the billing system, the marketing tool, the form plugin on the website — one of three things is true. It passes with alignment, and you leave it alone. It passes SPF or DKIM on the wrong domain, and you need a custom DKIM record or return-path on your domain from that vendor. Or it fails both, and you need to add it to SPF and set up DKIM. The alignment post walks through the vendor-side fixes.
Sources you do not recognise are either spoofing or forwarding. Forwarded mail — a recipient's rule that sends your message on to another mailbox — breaks SPF and often DKIM, and there is nothing you can do about it except accept a small residual failure rate. Everything else that is not yours is what the policy is for.
The source that bites is always the one nobody remembers: a legacy CRM still sending a monthly digest, a printer that emails scans, a website contact form on shared hosting. Wait for a full billing cycle before declaring the reports clean.
Stage 3: quarantine as a checkpoint
p=quarantine tells receivers to send failures to spam rather than reject them. It is the safety net: a legitimate source you missed lands in junk folders, someone notices, and you fix it without having bounced anything. Hold here for two weeks while watching reports. Under RFC 7489 you could stage this with pct=25 and increase gradually; RFC 9989 has removed pct, receivers implemented it inconsistently anyway, and the honest version is to go straight to quarantine at full strength once the reports are clean.
Stage 4: reject, and the subdomain policy
Change to p=reject. Then decide about subdomains. The sp= tag sets the policy for subdomains that have no DMARC record of their own; if you omit it, they inherit p. That is usually what you want, with one exception — sending subdomains like send.yourdomain or mail.yourdomain that use a different provider should get their own record with their own alignment mode, so the root domain can be strict while the subdomain stays relaxed. RFC 9989 adds np= for subdomains that do not exist at all; set it to reject.
A finished record looks like v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc@yourdomain; adkim=s; aspf=s. Strict alignment (s) requires an exact domain match; relaxed (r, the default) accepts organisational-domain matches. Go strict on the root only when every source signs with the root domain exactly. Build it with the generator.
Cold email fleets
Secondary sending domains should go to p=reject from the start. There is nothing else sending as them, the mail provider handles alignment, and a strict policy on a young domain is a small positive signal. The primary domain — the one clients and invoices come from — is the one that needs the four-stage treatment.
What to watch after enforcement
Keep the reports flowing. A new vendor onboarded by someone who does not know DMARC exists will show up as a new failing source, and at reject that means their mail vanishes. A weekly glance at the report parser catches it. Check the record itself periodically with the DMARC checker, which will tell you whether the policy is actually enforcing and flag the deprecated tags.
Sources
- RFC 9989 — DMARC — IETF
- RFC 9990 — DMARC Aggregate Reporting — IETF
- Set up DMARC — Google Workspace Admin Help
Tools for this
DMARC report parserRead the aggregate XML receivers send you.DMARC generatorBuild a valid record tag by tag.DMARC checkerSee whether your policy enforces anything.Frequently asked questions
How long should I stay on p=none?
Two to four weeks minimum, and at least one full billing or reporting cycle for any monthly senders. The reports need to show every legitimate source before you enforce.
Is quarantine safe enough to stay on permanently?
It is much better than none, but it leaves spoofed mail in spam folders where recipients can still open it. Reject is the destination; quarantine is the checkpoint.
What about pct?
RFC 9989 removed it. If your record still has pct below 100, either enforce fully and drop the tag or publish t=y to mark the policy as provisional. A partial pct is a rollout someone abandoned.
Will reject break forwarded mail?
Some of it. Mailing lists and forwarding rules can break SPF and DKIM, and at reject those messages are refused. ARC helps where the forwarder supports it. The residual loss is small and is the accepted cost of enforcement.
Do I need a different policy for sending subdomains?
Usually yes. A subdomain used by a different provider often needs relaxed alignment. Give it its own record so the root can stay strict.