How to set up DMARC, step by step
Updated ·9 min read
DMARC, specified by RFC 9989, which obsoleted RFC 7489 in May 2026, is the policy layer that sits on top of SPF and DKIM. It tells receiving mail servers what to do with a message that claims to be from your domain but fails to authenticate, and it gives you visibility into every source, legitimate or not, that is currently sending mail using your domain name.
Moving straight to a blocking policy without first seeing what is actually sending mail is the single most common way a DMARC rollout breaks legitimate email, often silently. This guide lays out a staged rollout, from p=none through to full enforcement at p=reject, with a checkpoint at each stage before moving to the next.
Check yours now
Stage 1: publish p=none and start collecting reports
The first record to publish at _dmarc.example is a monitoring-only policy: v=DMARC1; p=none; rua=mailto:dmarc-reports@example. p=none takes no action against failing mail; it exists purely to activate reporting. rua names the address where aggregate reports, sent roughly daily by participating receivers, will arrive.
Aggregate reports arrive as gzip-compressed XML and list, for every sending source seen for the domain, the sending IP, the volume of mail, and whether SPF and DKIM passed and were aligned with the visible From address. Most teams route these into a parsing dashboard rather than reading raw XML by hand, since even a modest domain can generate reports from dozens of distinct sources within the first week.
Stage 2: review reports until every legitimate source is accounted for
This stage has no fixed duration; it lasts until the reports stop surprising you. In practice that is commonly two to four weeks, long enough to capture weekly and monthly sending patterns such as an invoicing run or a newsletter that only goes out once a month.
For every sending IP or source shown in the reports, the goal is to answer one question: is this legitimate, and does it pass SPF or DKIM alignment? A legitimate source failing both is not yet a threat to block; it is a configuration gap to fix first, commonly a marketing platform sending as the domain without an SPF include, or a DKIM selector that was never set up for a particular sending tool.
- Add missing SPF includes for legitimate third-party senders identified in the reports
- Configure DKIM signing on any platform that supports it but was not yet set up
- Confirm the visible From domain used by each sender aligns with the authenticating domain, since alignment, not just a raw SPF or DKIM pass, is what DMARC actually checks
Stage 3: move to quarantine
Once reports show every legitimate source authenticating cleanly, move to v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example. Quarantine is itself the safe step: failing mail is set aside in a spam or junk folder rather than refused, so a source you missed is recoverable by the recipient instead of bouncing. Expect the change to affect delivery from the moment it is published — any sender still failing alignment starts being quarantined.
Do not reach for the pct tag to stage this further. RFC 9989 removed pct from DMARC entirely (Appendix A.6), and deployed receivers are now split: some still honour it, others ignore it and apply the policy in full. A record like p=quarantine; pct=25 therefore has no predictable meaning — you cannot say which of your mail is enforced — so it buys no real safety margin. Do not publish pct=100 either; full application is exactly what you get when the tag is absent.
Watch reports for a further one to two weeks at quarantine. The staging levers that still work are the policy level itself and the sp tag: sp=quarantine or sp=reject can be set for subdomains independently of the apex, and rolling back is a single edit to one TXT record, which takes effect within the record's TTL.
Stage 4: reach full enforcement at p=reject
Once quarantine has run cleanly for a period, typically another one to two weeks with no legitimate mail being quarantined, move to v=DMARC1; p=reject; rua=mailto:dmarc-reports@example. At this point, mail failing DMARC is rejected outright by participating receivers rather than merely flagged, which is what actually stops an attacker from sending a convincing spoofed message using the domain.
Keep the rua reporting address in place indefinitely after reaching p=reject, not just during the rollout. A new sending source, added months later without anyone remembering to update SPF or DKIM, will show up in reports as a failure before anyone notices missing mail, giving you a chance to fix it quietly rather than after a complaint.
Handling subdomains and third-party report authorization
By default, a domain's DMARC policy also applies to every subdomain, unless an sp tag sets a different policy specifically for them. A subdomain that never sends mail, such as a purely internal staging.example, is a common target for spoofing since it may have no SPF or DKIM of its own, so setting sp=reject early, even while the root domain is still at p=none, closes that gap without waiting for the full rollout.
Sending reports to a mailbox at a different domain than the one being protected requires that receiving domain to explicitly opt in, by publishing example.com._report._dmarc.otherdomain.example as a TXT record with the value v=DMARC1. Omitting this authorization record is a common reason a third-party monitoring service configured as the rua target never actually receives any reports, with no error visible anywhere in your own DNS.
A realistic overall timeline
Put together, a careful rollout from a fresh v=DMARC1; p=none record to a fully enforced p=reject typically spans four to eight weeks for a domain of ordinary complexity, not the single afternoon it takes to just publish the final record. Two to four weeks at p=none for report review and a further two to four weeks at p=quarantine, watching for legitimate mail being set aside, account for most of that time.
A domain with unusually many sending sources, such as a large organization where different departments independently signed up for their own marketing or support tools over the years, should expect the report-review stage specifically to take longer, since finding and fixing every gap is what that stage exists for, and rushing it is what causes legitimate mail to be blocked once enforcement begins.
Skipping stages to move faster is possible but changes the risk profile rather than removing it: publishing p=reject directly, without first seeing aggregate reports, means any gap in SPF or DKIM coverage is discovered only once mail from that source starts silently failing to arrive, rather than being visible in advance as a report to review calmly.
How to verify each stage before moving on
Two checks answer different questions and both are needed. Reading the record tells you what you asked receivers to do; reading the aggregate reports tells you what actually happened to your mail. A rollout that skips the second is a rollout conducted blind.
For the record: look it up directly rather than trusting the DNS panel, confirm exactly one TXT record exists at _dmarc, and run it through the DMARC checker so the effective policy — including the defaults for tags you did not write — is stated back to you. If the reporting address is at another domain, confirm that domain publishes the authorisation record, because without it compliant receivers send nothing and report no error anywhere.
For the reports: the question at every stage is the same. Does every source you recognise pass SPF or DKIM in alignment with the From domain, and is there anything sending as you that you do not recognise? Move on when the answer has been stable for the stage's full duration, not when the calendar says so.
There is one thing to watch that reports will not show. If you have set the t=y test-mode flag, receivers apply the policy one level below the one you declared: p=reject is treated as quarantine and p=quarantine as none. The record still reads as enforcing to most tools, which grade the p value they find. Ours does not — it grades the effective policy and raises a separate finding for the tag — but treat a record carrying t=y as still being at the lower policy wherever you are reading it, and give leaving it a date.
Rolling back, and what it costs
Every stage of this rollout is reversible with a single TXT record edit, and the change takes effect everywhere within that record's TTL. That is worth stating plainly, because fear of an irreversible mistake is the most common reason a domain stays at p=none for years.
What a rollback does not undo is the mail already refused. Under p=reject a failing message is rejected at the SMTP transaction, so the sender gets a bounce and the message is gone; under p=quarantine it is set aside where a recipient can still find it. That asymmetry is the entire argument for passing through quarantine rather than going straight to reject, and for keeping the MX record's TTL short enough that a rollback is measured in minutes.
If mail does start failing after a policy change, the fastest safe move is back to p=quarantine rather than back to p=none. Quarantine keeps the messages recoverable while you diagnose, and it does not surrender the protection you have built.
What commonly goes wrong
- Publishing p=none, meeting the mailbox providers' requirement, and stopping. It protects nothing. Set a date to move on when you publish it.
- Adding a pct tag to stage the rollout. RFC 9989 removed it, deployed receivers are split on whether they still honour it, and a record carrying it is enforced in full by some and sampled by others — so you cannot say which of your mail is enforced. It will also stop a BIMI logo displaying.
- An external reporting address with no authorisation record at the reporting domain, so the reports that the whole plan depends on never arrive.
- sp=none left in place from a template, which exempts every subdomain from an otherwise enforcing policy.
- Leaving subdomains that never send mail unprotected while the apex is staged. sp=reject and np=reject can both be published immediately, because there is no legitimate mail on those names to break.
- Turning on strict alignment while tightening the policy. Strict alignment breaks the common pattern of giving a bulk sender its own subdomain, and it is a frequent cause of legitimate mail failing after an otherwise clean rollout.