Skip to content

Exchange Online mail lands in spam: fix SPF, DKIM and DMARC

Service health is green, mail flow works, connectors look fine — but messages from your domain land in recipients’ Junk folder, or are rejected by Gmail, Yahoo or Outlook.com.

Almost always email authentication: a missing or broken SPF record, DKIM signing not enabled for your custom domain, or no DMARC record. Large mailbox providers now expect all three, and require them from high-volume senders.

Record What it proves Where it lives
SPF This server may send for my domain TXT record on the domain
DKIM The message wasn’t changed and really came from my domain Two CNAME records + signing enabled in Microsoft 365
DMARC What receivers should do when checks fail, and where to send reports TXT record at _dmarc.<domain>

If Microsoft 365 is your only sender:

v=spf1 include:spf.protection.outlook.com -all
  • Only one SPF record per domain — two v=spf1 records break SPF.
  • Add every legitimate sender (marketing, ticketing, HR tools) with its documented include:.
  • Stay under the 10 DNS lookup limit.
  • Use ~all (soft fail) first if you’re not sure every sender is listed.
  1. In the Microsoft Defender portal, go to Email & collaboration → Policies & rules → Threat policies → Email authentication settings → DKIM.
  2. Select your domain. Microsoft shows two CNAME records (selector1._domainkey and selector2._domainkey).
  3. Create both at your DNS host exactly as shown — the target format differs for newer domains, so don’t copy values from old articles.
  4. When DNS has updated, enable Sign messages for this domain with DKIM signatures.

Start in monitoring mode:

_dmarc.contoso.com TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@contoso.com"

Then tighten in stages once reports show all real senders passing: p=none → p=quarantine → p=reject.

Terminal window
# Exchange Online PowerShell
Connect-ExchangeOnline
Get-DkimSigningConfig | Select-Object Domain, Enabled, Status

DNS check from any Windows machine:

Terminal window
Resolve-DnsName contoso.com -Type TXT | Where-Object Strings -match 'v=spf1'
Resolve-DnsName _dmarc.contoso.com -Type TXT

Then open a received message’s headers and look at Authentication-Results — you want spf=pass, dkim=pass and dmarc=pass. Microsoft’s Message Header Analyzer makes headers easier to read.

Weekly · 5-minute read

The Identity Brief

Identity & Microsoft 365 changes that need action, one SOP, one script — every week. Verified against official Microsoft sources.

No spam. Unsubscribe anytime. Privacy