DMARC, SPF and DKIM for Microsoft 365

Updated 2026-11-06 ยท Published 2026-11-05

This guide is for admins who send from Microsoft 365 with a custom domain and want it at p=reject. Every Microsoft value below comes from Microsoft's own documentation on learn.microsoft.com, read in November 2026. For the background on each protocol, see SPF explained, DKIM explained and DMARC explained.

What Microsoft 365 sends from

Microsoft 365 sends mail for your custom domain, here example.com, from Microsoft's own servers. Three identities matter for authentication:

  • From address. The address users see, such as [email protected].
  • Envelope sender (MAIL FROM, Return-Path). Microsoft describes the MAIL FROM address as the address used between SMTP servers, typically recorded in the Return-Path header. In Microsoft's own header example for a DKIM-enabled domain, the envelope sender is in the customer domain ([email protected]). Microsoft's DMARC report table lists "Known IP (Microsoft 365), SPF aligned=pass" as normal Microsoft 365 mail flow.
  • DKIM signing domain (d=). As of November 2026, Microsoft states that "currently, no DKIM signing occurs for outbound mail from custom domains". Mail from the initial *.onmicrosoft.com domain (for example contoso.onmicrosoft.com) is DKIM signed automatically by that domain. Your custom domain needs its own DKIM setup.

SPF

There is no portal or PowerShell cmdlet in Microsoft 365 for SPF. You publish the record at your DNS host. Publish one TXT record on the domain name itself (example.com). As of November 2026, Microsoft documents these records for a domain that sends only through Microsoft 365:

Cloud SPF record
Microsoft 365 and GCC v=spf1 include:spf.protection.outlook.com -all
GCC High and DoD v=spf1 include:spf.protection.office365.us -all
Operated by 21Vianet v=spf1 include:spf.protection.partner.outlook.cn -all
example.com TXT "v=spf1 include:spf.protection.outlook.com -all"

Only one SPF record is allowed per name. Microsoft warns that more than one causes permerror. If example.com already has an SPF record for another service, add the include to that record instead of creating a second one. A typical setup, where include:_spf.example.net stands for another service, looks like this:

example.com TXT "v=spf1 include:spf.protection.outlook.com include:_spf.example.net -all"

This record uses 2 DNS lookups by itself, one per include. The limit is 10 (RFC 7208). Each include can also cost lookups inside its own record. Microsoft does not document a number for spf.protection.outlook.com. When we counted it with real DNS on 6 November 2026, it held only IP ranges, so it cost 1 lookup in total (the include itself) and nothing further. Microsoft can change that record, so count your own tree with the SPF lookup counter. Microsoft also says not to flatten its include into IP addresses, because its sending infrastructure uses IP addresses that change often.

Microsoft recommends -all for Microsoft 365 domains. Its reason: DMARC treats both -all and ~all as SPF failures, but the DMARC policy is effectively ignored for ~all failures when the message has no DKIM signature. Each subdomain that sends mail needs its own SPF record. See SPF multiple records for the most common error.

DKIM

Microsoft 365 uses two selectors per custom domain, selector1 and selector2. Both are CNAME records that point to keys Microsoft hosts. Only one selector signs at a time. The other is used after a key rotation.

The CNAME records

As of November 2026, Microsoft documents this format for new custom domains (introduced in May 2025):

selector1._domainkey CNAME selector1-<CustomDomainWithDashes>._domainkey.<InitialDomainPrefix>.<DynamicPartitionCharacter>-v1.dkim.mail.microsoft
selector2._domainkey CNAME selector2-<CustomDomainWithDashes>._domainkey.<InitialDomainPrefix>.<DynamicPartitionCharacter>-v1.dkim.mail.microsoft
  • <CustomDomainWithDashes> is your domain with dots replaced by dashes, so example.com becomes example-com.
  • <InitialDomainPrefix> is the custom part of your *.onmicrosoft.com domain.
  • <DynamicPartitionCharacter> is a character such as r or n that Microsoft assigns. You cannot choose it.

Existing custom domains keep the older format, which points to selector1-example-com._domainkey.<prefix>.onmicrosoft.com. Microsoft says the values on its page are for illustration only. Copy the exact targets from the Defender portal, or run Get-DkimSigningConfig -Identity example.com | Format-List Name,Enabled,Status,Selector1CNAME,Selector2CNAME in Exchange Online PowerShell.

Turn on signing in the Defender portal

These are Microsoft's steps as of November 2026:

  1. Add the domain to Microsoft 365 first.
  2. In the Defender portal at security.microsoft.com, go to Email & collaboration > Policies & rules > Threat policies > Email authentication settings, and open the DKIM tab.
  3. In the row for your domain, try to slide the toggle to Enabled. A client error dialog shows the CNAME values. Select OK. The status becomes CnameMissing.
  4. Open the domain's details flyout and copy the values under Publish CNAMEs.
  5. Create both CNAME records at your DNS host.
  6. After Microsoft detects them, which can take a few minutes or longer, select Sign messages for this domain with DKIM signatures. The status should read Signing DKIM signatures for this domain.

PowerShell and key length

In Exchange Online PowerShell, New-DkimSigningConfig creates the configuration and Set-DkimSigningConfig -Identity example.com -Enabled $true turns signing on. As of November 2026, the -KeySize parameter accepts 1024 (the default) or 2048. For a new configuration, use New-DkimSigningConfig -DomainName example.com -Enabled $false -KeySize 2048. For an existing domain, run Rotate-DkimSigningConfig -Identity example.com -KeySize 2048. The first rotation only moves the newly active selector to 2048 bits. The other selector gets 2048 bits at the next rotation, and each rotation takes four days (96 hours). RFC 8301 says signers should use 2048-bit keys, so choose 2048 where you can.

DMARC alignment

DMARC passes when SPF or DKIM passes and the domain it checked aligns with the From domain. SPF alignment compares the RFC5321.MailFrom (Return-Path) domain with the From domain. DKIM alignment compares the d= domain with the From domain. Relaxed alignment, the default for aspf and adkim, needs the same organisational domain. Strict needs an exact match.

For Microsoft 365 mail from example.com:

  • SPF. Microsoft's report table treats Microsoft 365 mail as SPF aligned. That alignment depends on example.com having an SPF record that authorises Microsoft 365. Forwarding breaks SPF, because the forwarding server is not in your record.
  • A signature from the initial domain. Microsoft's alignment table shows that a d=contoso.onmicrosoft.com signature on mail from [email protected] fails both relaxed and strict alignment. Until you set up DKIM for the custom domain, there is no aligned DKIM signature.
  • DKIM after setup. The signature carries d=example.com, which aligns in both modes. DKIM usually survives forwarding when the body is not changed, so it is the identity that keeps forwarded mail passing.

Mail sent through other services is separate. If a service uses its own domain in the envelope sender and signs with its own d=, it fails DMARC for example.com. Microsoft's fixes are to have the service sign with your domain, to change the MAIL FROM to your domain or a subdomain, or to send from a subdomain with its own records.

Step by step to p=reject

  1. Publish SPF. Create one TXT record on example.com with include:spf.protection.outlook.com (or the include for your cloud), merge in any other senders, and end it with -all as Microsoft recommends.
  2. Turn on DKIM. Publish both selector1._domainkey and selector2._domainkey CNAME records with the exact targets from the Defender portal or PowerShell, then enable signing and confirm the status is Valid or Signing DKIM signatures for this domain.
  3. Publish DMARC with p=none and rua. Create a TXT record at _dmarc.example.com with v=DMARC1; p=none; rua=mailto:[email protected], so receivers start sending aggregate reports without acting on failures yet (DMARC policy none is expected here).
  4. Read the reports and fix other senders. Look for sources that fail both SPF and DKIM alignment. Configure DKIM with your domain at each service, add them to SPF, or move them to a subdomain.
  5. Move to quarantine. When the reports show only legitimate mail passing, change the policy to p=quarantine.
  6. Move to reject. After a period at quarantine without unexpected failures, change the policy to p=reject and keep reading the aggregate reports for new senders.

If you do not send from your *.onmicrosoft.com domain, Microsoft says to add a DMARC record for it in the Microsoft 365 admin center.

_dmarc.example.com TXT "v=DMARC1; p=none; rua=mailto:[email protected]"
_dmarc.example.com TXT "v=DMARC1; p=reject; rua=mailto:[email protected]"

Microsoft's examples still use pct from RFC 7489. Some receivers support a test flag (t=y in RFC 9989 (DMARCbis) or pct in RFC 7489), but neither is a safety net: RFC 7489 says unknown tags must be ignored, so a receiver that implements only RFC 7489 can apply p=reject; t=y as a full reject. Step from p=none to p=quarantine to p=reject instead. Microsoft also notes that mail from Microsoft 365 that fails DMARC is routed through its High-risk delivery pool once the policy is p=quarantine or p=reject.

Common mistakes

  • Two SPF records. Microsoft says multiple SPF records on one name return permerror. Merge them into one.
  • Ending SPF with ~all and skipping DKIM. Microsoft notes the DMARC policy is effectively ignored for ~all failures on messages without a DKIM signature.
  • Flattening the Microsoft include. Microsoft advises against replacing include:spf.protection.outlook.com with IP addresses because its IPs change often.
  • A TXT record at selector1._domainkey. Microsoft lists this as incorrect and not supported. Use the CNAME records. See DKIM not found if the selector does not resolve.
  • Only one selector. Without selector2, key rotation fails. Publish both.
  • The domain added twice to the hostname. Many DNS hosts append the zone, so selector1._domainkey.example.com becomes selector1._domainkey.example.com.example.com. Enter only selector1._domainkey.
  • Building the CNAME target by hand. The partition character and initial domain prefix are easy to get wrong. Copy the values Microsoft shows.
  • Proxying the CNAME. At Cloudflare, Microsoft says to set the DKIM CNAME records to DNS only, because a proxied record breaks verification.
  • No report address. Without rua, you cannot see which senders fail. See DMARC without rua.

How to check it

Run the email security check after each step. Use the SPF lookup counter to see how many of the 10 lookups your record uses, including the Microsoft include. In the DKIM selector finder, look for selector1 and selector2. Build each DMARC stage with the DMARC record generator.

To check a single message, open its headers at the recipient. Look for d=example.com and s=selector1 or s=selector2 in the DKIM-Signature header, and dmarc=pass in Authentication-Results.

Sources

Frequently asked questions

Which SPF include does Microsoft 365 use?

As of November 2026, Microsoft documents include:spf.protection.outlook.com for Microsoft 365 and GCC, include:spf.protection.office365.us for GCC High and DoD, and include:spf.protection.partner.outlook.cn for Microsoft 365 operated by 21Vianet.

Does Microsoft 365 sign mail from my custom domain with DKIM by default?

As of November 2026, no. Microsoft's DKIM page says that currently no DKIM signing occurs for outbound mail from custom domains. Mail from the initial *.onmicrosoft.com domain is signed automatically. You have to publish two CNAME records and turn on signing for each custom domain.

Can I publish the DKIM key as a TXT record instead of a CNAME?

No. Microsoft lists a TXT record at selector1._domainkey as incorrect and not supported. Microsoft 365 manages the keys and rotation, and the CNAME records delegate that to Microsoft.

Will Microsoft 365 send me DMARC reports?

As of November 2026, Microsoft 365 sends aggregate reports to domains with a valid rua=mailto: address when the MX record of the receiving Microsoft 365 domain points directly to Microsoft 365. If that mail is routed through another service first, no report is sent. Microsoft 365 does not send forensic (failure) reports, even when a ruf= address is published.