How to Set Up DMARC for Microsoft 365

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

Quick answer

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.

What DMARC checks

A message passes DMARC when SPF or DKIM passes and is aligned with the domain in the visible From address:

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=).

Step 1: Prerequisites (SPF and DKIM)

  1. SPF: one record per sending domain, for example 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.
  2. DKIM: turn on DKIM signing for every custom domain and subdomain that sends from Microsoft 365. See How to enable DKIM in Microsoft 365. DKIM matters most because it survives forwarding, which breaks SPF.
  3. Third-party senders: each one must either sign DKIM with your domain or use a MAIL FROM in your domain. Otherwise it fails DMARC once you enforce.

Step 2: onmicrosoft.com vs custom domains

Step 3: Decide where reports go (rua)

Step 4: Publish p=none and monitor

Host:  _dmarc
Type:  TXT
Value: v=DMARC1; p=none; rua=mailto:dmarc-reports@contoso.com
  1. Publish exactly one TXT record at _dmarc. Two DMARC records means receivers ignore DMARC for the domain.
  2. Confirm it with the DMARC Record Checker and the DNS Propagation Checker (TXT, name _dmarc.contoso.com).
  3. Watch the reports for at least a few weeks, including month-end runs (invoices, payroll, newsletters). For every source IP, work out who it is. Fix legitimate senders (SPF include and/or DKIM with your domain, or move them to a subdomain). Ignore spoofers: that's the traffic DMARC will block.

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.

Step 5: Move to quarantine, gradually

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.

Step 6: Move to reject

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.

Step 7: Subdomains (sp=)

How Microsoft 365 handles inbound DMARC

Common DMARC mistakes

Audit hundreds of domains at once

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).

Related tools and guides

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.

FAQ

What DMARC record should I use 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.

Do I need DMARC for my onmicrosoft.com domain?

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).

How long should I stay at p=none?

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.

Is pct still supported in DMARC?

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.

Why does Microsoft 365 show compauth=fail when the sender has no DMARC record?

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.

Want the full kit?

Runbooks, checklists and helpdesk templates: IT Admin Packs on Gumroad.