Set up DMARC for Microsoft 365 step by step: SPF and DKIM prerequisites, onmicrosoft.com and custom domains, a safe p=none to quarantine to reject rollout, rua reports, sp= for subdomains, and how Microsoft 365 handles inbound DMARC.
Home › Guides › DMARC for Microsoft 365
Last updated 16 October 2026
Once SPF and DKIM are working for your custom domain, publish a TXT record on host _dmarc (so _dmarc.contoso.com):
v=DMARC1; p=none; rua=mailto:dmarc-reports@contoso.com
Read the aggregate reports, fix every legitimate sender that fails, then move to p=quarantine and finally p=reject. Microsoft's goal for every custom domain and subdomain is p=reject. Build the record with the DMARC Record Generator and check it with the DMARC Record Checker.
A message passes DMARC when SPF or DKIM passes and is aligned with the domain in the visible From address:
d=) matches the From domain.Alignment is relaxed by default (aspf=r, adkim=r), so bounces.contoso.com aligns with contoso.com. A signature from contoso.onmicrosoft.com or a vendor's own domain does not align with contoso.com. If both checks fail, the receiver applies your policy (p=).
v=spf1 include:spf.protection.outlook.com -all. See How to set up SPF for Microsoft 365, or use the SPF Builder and SPF Checker._dmarc, value v=DMARC1; p=reject (add rua=mailto:... if you want reports). If you don't send from it, p=reject is exactly right.v=DMARC1; p=reject; straight away, along with SPF v=spf1 -all.dmarc-reports@contoso.com), not someone's personal mailbox. Reports are XML files (often gzipped), usually sent daily by each receiver.contoso.com._report._dmarc in the vendor's zone with value v=DMARC1;. Reputable vendors already do this.ruf (failure/forensic reports) at first. Few receivers send them, and Microsoft 365 never does.Host: _dmarc Type: TXT Value: v=DMARC1; p=none; rua=mailto:dmarc-reports@contoso.com
_dmarc. Two DMARC records means receivers ignore DMARC for the domain._dmarc.contoso.com).p=none already counts as a DMARC record for Outlook.com's high-volume sender rules (in force since May 5, 2025: domains sending more than 5,000 messages a day to Outlook.com, Hotmail and Live addresses must pass SPF and DKIM and have DMARC of at least p=none, aligned with SPF or DKIM). It doesn't protect you from spoofing, though.
Microsoft's documented rollout raises the percentage of failing mail that gets the policy:
v=DMARC1; p=quarantine; pct=10; rua=mailto:dmarc-reports@contoso.com v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc-reports@contoso.com v=DMARC1; p=quarantine; pct=50; rua=mailto:dmarc-reports@contoso.com v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@contoso.com
Leaving out pct means 100%. Start with low-volume subdomains and save the busy parent domain for last.
Note on the new DMARC standard: RFC 9989 (May 2026, replacing RFC 7489) removes pct and adds a test-mode tag, t=y, which asks receivers to apply one level less (reject is treated as quarantine, quarantine as none). Receivers are moving to it at different speeds, and a receiver that follows RFC 9989 ignores pct, so it can apply your policy to 100% of failing mail even while you publish pct=25. Only raise the policy once reports show legitimate mail passing. If you want an explicit test step that both older and newer receivers understand, publish pct=0; t=y together, which means one level less under both standards.
v=DMARC1; p=reject; rua=mailto:dmarc-reports@contoso.com
Keep reading reports afterwards. New SaaS tools get bought and start sending as your domain without anyone telling IT.
_dmarc record.sp= sets a different policy for subdomains. For example, v=DMARC1; p=reject; sp=quarantine; rua=... rejects for contoso.com but only quarantines subdomains while a marketing subdomain is being fixed._dmarc.marketing.contoso.com with p=none while you onboard a vendor. Remember it also needs its own SPF and DKIM.np=, a policy for subdomains that don't exist in DNS. np=reject is a good choice once you're enforcing; receivers that don't support it yet fall back to sp or p.p=quarantine and p=reject. Microsoft recommends keeping it on. Check yours with Get-AntiPhishPolicy | Format-List Name,HonorDmarcPolicy,DmarcQuarantineAction,DmarcRejectAction.p=quarantine domain goes to Junk Email (or quarantine, if configured), and mail from a p=reject domain is rejected during SMTP.Authentication-Results: dmarc=pass, dmarc=fail action=quarantine, action=oreject (sender's policy was reject), action=pct.quarantine/pct.reject (pct sampling), or dmarc=bestguesspass (no DMARC record; Microsoft inferred a pass).compauth=fail reason=100 means the sender's DMARC policy caused it; reason=000 is an explicit authentication failure. Paste headers into the Email Header Analyzer to see all of this decoded.@) instead of _dmarc, or publishing two _dmarc records.rua=dmarc@contoso.com without the mailto: prefix, or an external rua address without the authorization record.p=reject before DKIM is on for every custom domain, which leaves DMARC depending on SPF alone and breaks forwarded mail.aspf=s / adkim=s) without a reason. Relaxed is fine for nearly everyone.p=none protects anything. It only gives you reports.Need SPF, DMARC and MX checks across a whole client list? Run the Bulk SPF / DMARC / MX Auditor on Apify ($2 per 1,000 domains).
Generate and check records with the DMARC Record Generator and DMARC Record Checker, audit the whole domain with the Email Deliverability Checker, decode Authentication-Results and compauth with the Email Header Analyzer, and confirm changes with the DNS Propagation Checker. Going further: MTA-STS and TLS-RPT protect mail in transit. Prerequisites: SPF and DKIM for Microsoft 365.
Start with v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain as a TXT record on host _dmarc, after SPF and DKIM are working. Move to p=quarantine and then p=reject once aggregate reports show all legitimate mail passing.
Yes. Microsoft handles SPF and DKIM for it, but you add the DMARC TXT record yourself in the Microsoft 365 admin center under Settings, Domains, the onmicrosoft.com domain, DNS records, Add record (name _dmarc, value v=DMARC1; p=reject).
Long enough to see every legitimate sender in your aggregate reports, usually at least a few weeks including month-end and any newsletters or billing runs. Move on when the only failing sources are ones you do not recognise.
RFC 9989 (May 2026) removed pct and added t=y for test mode. Many receivers still honour pct, and Microsoft documentation still shows it, but newer receivers may ignore it and apply your full policy. Only raise the policy when your reports are clean.
Composite authentication is Microsoft's own verdict. It combines SPF, DKIM, DMARC, ARC and spoof intelligence, so a message can fail compauth (for example with reason 000) even without a DMARC policy. reason=100 means the sender's DMARC policy caused the failure.
Runbooks, checklists and helpdesk templates: IT Admin Packs on Gumroad.