How to set up DMARC, step by step

By the zmam.ai team ·

There are two ways to deploy DMARC. The reckless way is to publish p=reject on day one and discover, from the angry calls, which of your own systems you just cut off from the inbox. The safe way takes a few weeks, blocks nothing by surprise, and ends in exactly the same place. This is the safe way.

DMARC builds on SPF and DKIM, so make sure both exist first — see SPF, DKIM, and DMARC explained .

Step 1 — start by listening

Publish one TXT record at _dmarc.example.com that takes no action and only asks for reports:

v=DMARC1; p=none; rua=mailto:[email protected]

p=none cannot break anything. It simply tells the world’s mailbox providers to start mailing you aggregate reports about who is sending as your domain. This step is risk-free, and skipping it is how people break their own mail.

Step 2 — read what comes back

Within a day or two the XML reports start arriving. They list every source sending mail as your domain and whether each one passes SPF and DKIM alignment. Raw DMARC XML is miserable to read by hand, so use a report viewer. Your goal is a complete census of your legitimate senders — the mail platform, the CRM, the helpdesk, the invoicing tool, the marketing service nobody remembered to mention.

This census is the real work of DMARC. Almost every painful rollout fails here, not in the syntax.

Step 3 — fix the gaps

For each legitimate sender that is failing, fix it: add it to SPF, enable DKIM signing for it, or both. Do not advance until your real mail passes consistently.

Step 4 — quarantine (partial enforcement)

Once legitimate mail passes reliably, tighten the policy so failures land in spam:

v=DMARC1; p=quarantine; rua=mailto:[email protected]

Older rollout guides recommended the pct tag for partial enforcement. Do not rely on it now: RFC 9989 (the 2026 DMARC standard) removed pct because receivers applied it inconsistently. Stage the rollout operationally instead — watch the aggregate reports at each step and advance only when legitimate mail passes cleanly. If you want to signal a non-enforcing trial, RFC 9989 adds a t=y “testing” tag for that purpose.

Step 5 — reject

When the reports are clean, enforce:

v=DMARC1; p=reject; rua=mailto:[email protected]

At p=reject, receivers refuse mail that fails authentication. This is the line that actually stops an attacker from spoofing your domain — and the line that most organizations never cross. Industry surveys consistently find that a majority of domains with DMARC are stranded at p=none: monitoring forever, protecting nothing.

How zmam.ai helps

zmam.ai reports your current DMARC policy and flags the classic stall — a domain parked at p=none long after setup, collecting reports while remaining wide open to impersonation. The check is read-only and uses public DNS.