Exchange Online mail lands in spam: fix SPF, DKIM and DMARC
Error / symptom
Section titled “Error / symptom”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> |
1. SPF
Section titled “1. SPF”If Microsoft 365 is your only sender:
v=spf1 include:spf.protection.outlook.com -all- Only one SPF record per domain — two
v=spf1records 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.
2. DKIM
Section titled “2. DKIM”- In the Microsoft Defender portal, go to Email & collaboration → Policies & rules → Threat policies → Email authentication settings → DKIM.
- Select your domain. Microsoft shows two CNAME records (
selector1._domainkeyandselector2._domainkey). - Create both at your DNS host exactly as shown — the target format differs for newer domains, so don’t copy values from old articles.
- When DNS has updated, enable Sign messages for this domain with DKIM signatures.
3. DMARC
Section titled “3. DMARC”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.
PowerShell check
Section titled “PowerShell check”# Exchange Online PowerShellConnect-ExchangeOnlineGet-DkimSigningConfig | Select-Object Domain, Enabled, StatusDNS check from any Windows machine:
Resolve-DnsName contoso.com -Type TXT | Where-Object Strings -match 'v=spf1'Resolve-DnsName _dmarc.contoso.com -Type TXTThen 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