MailCheck

DMARC setup: from p=none to p=reject without losing mail

DMARC ties SPF and DKIM to the sender address your recipients actually see. It also tells other servers what to do with forgeries.

Updated: 05 November 2026

What DMARC checks

SPF and DKIM each check a domain, but not necessarily the one in the From line. DMARC (RFC 9989, successor to RFC 7489) adds that check. A message passes DMARC if at least one of these holds:

  • SPF passes and the envelope domain matches the From domain.
  • DKIM passes and the domain in d= matches the From domain.

"Matches" normally means the same organisational domain, so mail.example.com matches example.com. With aspf=s or adkim=s you require an exact match, which is rarely necessary.

If a message fails, your policy applies.

The DMARC record

DMARC is a TXT record at _dmarc under your domain:

_dmarc.example.com.  TXT  "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
Tag Meaning
p= policy: none (monitor only), quarantine (junk folder), reject
rua= address for the daily aggregate reports
sp= separate policy for subdomains, otherwise p= applies
pct= share of mail the policy applies to (default 100); dropped in RFC 9989, which has t=y for a test mode instead
adkim= / aspf= r (relaxed, default) or s (strict)

What the reports tell you

With rua, the large mailbox providers send you an XML file every day. It lists which IP addresses sent mail using your domain, how much, and whether SPF and DKIM lined up. Senders nobody remembered turn up, such as the old website or the survey tool. The colleague who writes from a personal account with the company address shows up too, and so do forgers using your domain for phishing.

If the report address lives on another domain, for example with an analysis service, that domain has to accept the reports. It needs a record like example.com._report._dmarc.reports.example containing v=DMARC1. Without it, compliant reporters send no reports there.

Hardly anyone enjoys reading the XML by hand. A tool such as ZwoMailHygiene's DMARC monitoring summarises the reports for you.

Getting to p=reject

Publish p=reject straight away and you may well lock out your own invoices. Going in stages is safer:

  1. Watch. Publish p=none with rua and collect reports for two to four weeks.
  2. Tidy up. Add every legitimate sender to SPF or, better, have it sign with DKIM for your domain. Chase down anything nobody recognises.
  3. Tighten. Move to p=quarantine and keep reading the reports.
  4. Finish. p=reject for all mail.

p=none is meant for the monitoring phase and protects nobody. Since February 2024, Google and Yahoo require bulk senders to publish a DMARC record, and their messages must pass DMARC; p=none is enough for that. Google draws the line at 5,000 messages a day to Gmail accounts, Yahoo gives no number. Only quarantine or reject protects against phishing with your domain.

Common mistakes

  • Two DMARC records at _dmarc. Receivers ignore both.
  • A missing semicolon, or p=rejected instead of p=reject. An invalid p value removes the protection, and receivers treat the record as p=none at best.
  • p=reject while the newsletter service still signs with its own domain. Those messages fail and never arrive.
  • Overlooked subdomains. They inherit the parent domain's policy unless they publish their own _dmarc record or sp= says otherwise. If a subdomain sends mail itself, check its entries in the reports separately.

Checking DMARC

Send a test message to ZwoMailCheck. The result page lists policy, report address and subdomain rule and, more to the point, shows whether your message passes DMARC via SPF, via DKIM or not at all.