By Ahmet Karaca · Updated · Checked against RFC 9989 (DMARC, May 2026), RFC 9990 (DMARC aggregate reports) and RFC 7489 (DMARC) on
DMARC record syntax
A DMARC record is a list of tag=value pairs separated by semicolons. DMARC was first written up in RFC 7489, an informational document. In May 2026 it became a Standards Track protocol as RFC 9989, which obsoletes RFC 7489 and moves aggregate reporting into RFC 9990. The tags below follow RFC 9989 and note where the older document differs.
v=DMARC1is required and must be the first tag. Without it the TXT record is not a DMARC record at all.pis the policy for mail that fails DMARC:none,quarantineorreject. RFC 7489 required it straight afterv; RFC 9989 calls it recommended and treats a record without it asp=none.spsets a separate policy for existing subdomains. When it is missing, subdomains get the value ofp.np, new in RFC 9989, sets the policy for subdomains that do not exist in DNS. When it is missing,spor elsepapplies.rualists themailto:addresses that receive aggregate reports. Without it, receivers send no aggregate reports at all, so you cannot see who sends as your domain.rufasks for per-message failure reports, andfopicks which failures trigger them (0by default: only when nothing produced an aligned pass).fois ignored unlessrufis present.adkimandaspfchoose relaxed (r, the default) or strict (s) alignment between the From domain and the DKIM or SPF domain. Relaxed letsmail.example.comcount forexample.com; strict demands the exact name.t, new in RFC 9989, marks a policy as being tested. Witht=yreceivers apply one level below the published policy, sop=reject; t=yis treated like quarantine andp=quarantine; t=ylike monitoring.t=nis the default. It replacespct, which RFC 7489 used to apply a policy to a percentage of failing mail: only 0 and 100 were applied consistently, so RFC 9989 removedpct, together withrfandri.
The form above writes v, p and rua. Testing mode adds t=y; pct=0: receivers that follow RFC 9989 read t=y, older ones read pct=0, and both hold the policy back. Importing a record that still uses pct=25 or pct=50 drops it, along with rf and ri. The form leaves the alignment tags at their relaxed defaults by omitting them. Add sp, np or ruf by hand if you need them.
Example records
Monitoring mode changes nothing about delivery and only collects reports:
_dmarcv=DMARC1; p=none; rua=mailto:dmarc-reports@example.comMonitoring: reports only
The middle stage sends failing mail to spam while reports keep arriving:
_dmarcv=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.comQuarantine: failing mail goes to spam
Before rejecting, test the stricter policy. Receivers treat failing mail one level softer while reports keep arriving:
_dmarcv=DMARC1; p=reject; t=y; pct=0; rua=mailto:dmarc-reports@example.comReject in testing mode: receivers apply quarantine instead
Full enforcement blocks failing mail on the domain and on every subdomain:
_dmarcv=DMARC1; p=reject; sp=reject; rua=mailto:dmarc-reports@example.comReject on the domain and its subdomains
Choosing a policy
Before publishing p=none, make sure SPF and DKIM exist for the services you know about and that the rua mailbox can take machine-generated XML. RFC 9989 recommends starting here because in all but the most trivial setups a server or a third-party sender gets overlooked.
Before moving to quarantine, the reports should show every legitimate source passing with an aligned identifier. Anything that fails and is yours, such as a CRM or a billing system, has to be fixed first. Depending on how often you send, that can take months of reports.
Before moving to reject, understand forwarding. Alumni addresses, role aliases and mailing lists relay your mail from their own servers, so SPF fails there while DKIM usually survives. RFC 9989 therefore says a domain at p=reject must sign with DKIM rather than rely on SPF alone, and that domains whose users post to mailing lists should run p=none for at least a month and p=quarantine for as long again before rejecting. The staged plan from p=none to p=reject covers every step, including how to roll back.
Report addresses on another domain
If example.com sends its reports to reports@example.net, receivers first ask example.net whether it agrees. They look up a TXT record built from the policy domain, _report._dmarc and the destination host. If no record starting with v=DMARC1 is there, the address must be ignored and those reports never arrive. Whoever runs example.net publishes:
example.com._report._dmarc.example.netv=DMARC1Lets example.net receive reports about example.com
A report service that accepts reports for any domain can publish the same value once at *._report._dmarc.example.net. Our DMARC checker looks this record up for every external report address and warns when it is missing.
Publishing it
Create a TXT record with the host _dmarc; most DNS panels add your domain, so the full name becomes _dmarc.example.com. Keep exactly one record at that name: under RFC 9989, receivers that find several discard them all, and RFC 7489 stopped DMARC processing in the same case. Then check the live record with the DMARC record checker, and if a provider still fails, follow its Microsoft 365 DKIM and DMARC setup guide or the matching guide for your sender.