DMARC Engine
Home/Blog/DMARC for Microsoft 365
Blog

DMARC for Microsoft 365

A practical, ordered guide to email authentication on Microsoft 365: build a complete SPF record for Exchange Online, enable DKIM signing with Microsoft's two selector CNAMEs, and walk DMARC safely from p=none through quarantine to p=reject without breaking your mail.

22 June 2026 · 6 min read

DMARC for Microsoft 365

DMARC for Microsoft 365 takes three pieces of work: an SPF record that includes Exchange Online, DKIM signing switched on for each custom domain, and a DMARC record that you move from p=none to p=reject once the reports show nothing legitimate is failing. Microsoft's domain setup asks you for the SPF record. DKIM and DMARC are left to you.

The steps below follow Microsoft's own documentation, which changed in 2025: new custom domains now get DKIM CNAME targets in a new format, so older guides that show a .onmicrosoft.com target may not match what your tenant asks for.

Step 1: SPF for Exchange Online

For a domain that only sends through Microsoft 365, Microsoft's SPF guidance gives this record:

DNS record
v=spf1 include:spf.protection.outlook.com -all

Publish it as a TXT record at the root of the domain. Three points matter:

  • List every other sender. Marketing platforms, CRMs, help desks, invoicing tools and on-premises servers that send as your domain each need their own entry in the same record, for example v=spf1 include:spf.protection.outlook.com include:sendgrid.net -all. Microsoft suggests moving services you do not control to a subdomain such as marketing.example.com, with its own SPF record.
  • One SPF record per name. Two v=spf1 records on the same name returns permerror. Merge them.
  • Ten lookups at most. Every include, a, mx, exists and redirect costs a DNS lookup, nested includes count too, and more than ten fails SPF. Microsoft advises against flattening its own include because its IP addresses change frequently.

Microsoft recommends -all rather than ~all. Its documentation explains that the DMARC policy is effectively ignored for SPF soft fails on messages that carry no DKIM signature, and that -all lets DMARC act on them.

Check the record and its lookup count with the SPF checker.

Step 2: turn on DKIM for your custom domain

Microsoft 365 does not DKIM-sign mail from a custom domain until you configure it. Mail from the initial *.onmicrosoft.com domain is signed automatically, but a signature for onmicrosoft.com does not align with a From address on example.com.

Microsoft uses two selectors, published as CNAME records that point at keys Microsoft holds:

Example
selector1._domainkey   CNAME   selector1-example-com._domainkey.example.n-v1.dkim.mail.microsoft
selector2._domainkey   CNAME   selector2-example-com._domainkey.example.n-v1.dkim.mail.microsoft

In the target, example-com is your custom domain with dots replaced by dashes, and example is the prefix of your *.onmicrosoft.com domain. The single letter before -v1 (for example n or r) is assigned by Microsoft. This format applies to custom domains added since May 2025. Domains configured before then keep the old target, selector1-example-com._domainkey.example.onmicrosoft.com. The two formats cannot be mixed for the same selector, so always copy the values Microsoft gives you rather than building them by hand.

To get the values and enable signing:

  1. In the Defender portal, go to Email & collaboration > Policies & rules > Threat policies > Email authentication settings and open the DKIM tab.
  2. Select your domain. If no keys exist yet, choose Create DKIM keys. The Publish CNAMEs section then shows both records.
  3. Create both CNAME records at your DNS host. Enter only selector1._domainkey and selector2._domainkey as the host names if your provider appends the domain itself.
  4. Wait for Microsoft to detect the records, then switch on Sign messages for this domain with DKIM signatures. While the records are missing, the status reads CnameMissing and the toggle will not stay on.

You can also read the exact values in Exchange Online PowerShell:

Example
Get-DkimSigningConfig -Identity example.com | Format-List Name,Enabled,Status,Selector1CNAME,Selector2CNAME

Only one selector signs at a time. The other is used after a key rotation, which you start with Rotate DKIM keys in the same flyout or with Rotate-DkimSigningConfig. A rotation takes four days to complete, and Rotate-DkimSigningConfig -KeySize 2048 moves the domain to 2048-bit keys. Because both records are CNAMEs, a rotation needs no DNS change, but only if both records stay published.

Each custom domain and each sending subdomain needs its own DKIM configuration. Check the published key with the DKIM checker for the selectors selector1 and selector2, then send yourself a message and confirm the DKIM-Signature header shows d=example.com.

Step 3: publish DMARC at p=none

DMARC is a TXT record at _dmarc.example.com. Start in monitoring mode:

DNS record
v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com
  • p=none takes no action on failing mail. It turns on reporting.
  • rua= is where receivers send daily aggregate reports listing every source that sent mail as your domain, and whether SPF and DKIM passed and aligned. Microsoft suggests a dedicated mailbox, not a person's inbox.
  • Leave adkim and aspf out. Both default to relaxed, which lets a subdomain such as bounces.example.com align with example.com. Strict alignment breaks that, and Microsoft's troubleshooting guide lists aspf=s as a common cause of failures for subdomain senders.
  • Adding ruf= and fo= asks for per-message failure reports, but Microsoft 365 does not send them and many other receivers do not either.

Build the record with the DMARC generator and read the reports in the DMARC report analyser. Normal Microsoft 365 traffic should show both SPF and DKIM aligned. Anything else that fails is either a legitimate sender you still need to authenticate, or someone spoofing your domain.

Step 4: quarantine, then reject

When every legitimate source passes, move the policy up:

DNS record
v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com

and once quarantine has run cleanly:

DNS record
v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com

Microsoft's DMARC article still shows a pct= ramp, but the current DMARC standard, RFC 9989, removed pct=. The replacement is the test flag t=y, which asks receivers to apply one level less than the published policy. RFC 9989 suggests at least a month at p=none and a similar period at p=quarantine, and it says domains whose users post to mailing lists SHOULD NOT publish p=reject, because lists that modify messages break DKIM.

Microsoft also suggests rolling out to low-volume subdomains first and leaving the parent domain until last.

Parked domains and the onmicrosoft.com domain

For domains you own but never send from, Microsoft recommends v=spf1 -all for SPF and v=DMARC1; p=reject; at _dmarc, with no DKIM records. If you do not send from your *.onmicrosoft.com domain, add a DMARC record for it too, in the Microsoft 365 admin centre under Settings > Domains.

How Microsoft 365 treats inbound mail that fails DMARC

Your own DMARC record protects you wherever your mail is received. Separately, inbound mail into your tenant is judged by your anti-phishing policy. With Honor DMARC record policy when the message is detected as spoof turned on, which Microsoft recommends, a sender's p=reject causes a rejection during SMTP with 550 5.7.1, and p=quarantine sends the message to Junk Email. Microsoft 365 sends aggregate reports to other domains only when your MX record points directly at Microsoft 365.

Microsoft 365 checklist

  1. One SPF record with include:spf.protection.outlook.com and every other sender, ending -all.
  2. Both DKIM CNAMEs, copied from the Defender portal, with signing enabled for every custom domain.
  3. DMARC at p=none with a dedicated rua mailbox.
  4. Reports showing every legitimate source aligned.
  5. p=quarantine, then p=reject.

Run the DMARC checker to see where your domain stands now. Related reading: how to rotate DKIM keys safely and p=none vs quarantine vs reject. If you would rather hand over the staged rollout and the report reading, hosted DMARC does both.

Share

See where your domain stands today

Run a free DMARC scan, then let us take you to enforced p=reject with no email outage.