How to set up DMARC and move safely to enforcement
DMARC tells receiving mail servers what to do with mail that claims to come from your domain but fails authentication, and where to send reports about it. It builds on SPF and DKIM: a message passes DMARC when SPF or DKIM passes and the domain that passed matches the domain in the visible From address. Gmail, Yahoo and Outlook.com all require a DMARC record from bulk senders (Gmail and Outlook.com put the line at 5,000 messages a day; Yahoo does not publish one). A policy of p=none meets that requirement, but only an enforcing policy stops spoofing.
Start by monitoring
Add a TXT record at _dmarc (that is, _dmarc.example.com):
v=DMARC1; p=none; rua=mailto:[email protected]
p=none changes nothing about delivery. rua asks receivers to send daily aggregate reports, as XML attachments, listing every server that sent mail as your domain and whether it passed. Use a dedicated mailbox, or a DMARC reporting service that turns the XML into something readable. If the report address is on a different domain from the one being reported on, that domain has to publish a record authorizing it; reporting services tell you what to add.
Fix every legitimate sender
After a week or two, the reports show every source sending as your domain. For each one you recognize (your mailbox provider, newsletter platform, CRM, invoicing, help desk, website forms), make sure it passes SPF or DKIM with your domain. DKIM is the more reliable of the two, because it usually survives forwarding and most services can sign with your domain once you add their records. Sources you do not recognize are either tools someone forgot to mention or someone spoofing you.
Move to enforcement in steps
v=DMARC1; p=quarantine; rua=mailto:[email protected]
v=DMARC1; p=reject; rua=mailto:[email protected]
p=quarantine asks receivers to treat failing mail as suspicious, usually by sending it to spam; p=reject asks them to refuse it. Spend a few weeks at each step, longer if you have many senders. At each step, watch the reports for legitimate mail that starts to fail, and keep the rua address so you keep seeing them.
If people at your domain post to mailing lists, be careful with p=reject. Many lists change messages in ways that break DKIM and send them on from their own servers, so list mail can fail DMARC and be refused. The current DMARC standard (RFC 9989) says such domains should not publish p=reject without first spending at least a month at p=none and a similar period at p=quarantine, comparing the reports. For them, p=quarantine may be the place to stop.
Older guides, including Google's own DMARC help, ramp up with pct=, applying the policy to a percentage of failing mail. RFC 9989 (2026) removed it because receivers applied it inconsistently, so receivers that follow the new standard may ignore it. Its replacement is t=y, a test flag that asks receivers to apply the policy one step softer: quarantine as none, reject as quarantine. Receivers that predate the new standard ignore t=y and apply the full policy, and Google's help does not mention it yet.
Tags worth knowing
| Tag | What it does |
|---|---|
p | Policy for the domain: none, quarantine or reject. Always include it; a record without a valid policy is treated as p=none at best. |
rua | Where aggregate reports go. Without it you have no visibility. |
sp | Policy for subdomains, if different from p. |
adkim, aspf | Alignment: r (relaxed, the default) lets mail.example.com align with example.com; s (strict) needs an exact match. |
np | Policy for subdomains that do not exist. Added to the main standard in RFC 9989 (it started in an experimental 2021 spec); receivers that do not support it fall back to sp or p. |
t | Test mode. t=y asks receivers to apply the policy one step softer while you check the reports. Replaces the old pct tag; not every receiver supports it yet. |
ruf | Where per-message failure reports go. Many receivers, Gmail included, do not send them. |
Common problems
- The record is on the wrong name. DMARC must be at
_dmarc.example.com, not on the domain itself. - Two DMARC records. Receivers ignore both. Keep one.
- The record does not start with
v=DMARC1. It must be the first tag, or receivers ignore the whole record. Putp=straight after it. A missing or misspelled policy is treated asp=noneif the record has a validruaaddress, and ignored if it does not. - Stuck at
p=none. Monitoring is a starting point, not protection. Anyone can still send mail that looks like yours. - Domains that never send email still need protecting. Publish
v=DMARC1; p=reject; rua=mailto:[email protected]at_dmarc,v=spf1 -allon the domain itself, and a null MX record (0 .) if it receives no mail either.
Check it worked
Run WEBCHKR again. The DMARC Record check passes for any valid record, including p=none, and then tells you what is still worth doing: that a none policy only monitors, that t=y test mode is on, that an obsolete pct= tag will not give you a gradual rollout, or that there is no rua address for reports. It fails if the record is missing or malformed, and says whether receivers will ignore it or treat it as p=none.