ZeroHookZeroHook
Back to Blog

Microsoft 365 SPF Record Template

The correct microsoft 365 spf record for Exchange Online, plus when to add ESP includes and how to avoid PermError on crowded TXT records.

ZeroHook TeamJun 29, 2026~3 min read
Microsoft 365 SPF Record Template

You migrated to Microsoft 365 in a weekend. Monday morning, marketing asks why SPF still points at the old Google include. A 41-person professional services firm in Copenhagen left include:_spf.google.com in DNS for eleven months after moving mailboxes to Exchange Online. Outbound mail mostly worked. SPF evaluation returned pass for Google's range, not Microsoft's. DMARC alignment failed on some hybrid calendar invites. A client's gateway quarantined proposals until someone noticed the TXT record never changed. The microsoft 365 spf record is not complicated. One include covers standard Exchange Online outbound. Complexity shows up when you stack marketing tools, ticketing SaaS, and payroll systems on the same domain without counting DNS lookups.

Microsoft 365 SPF Record (Exchange Online Only)

If every message leaves through Microsoft 365 and no third-party tool sends as your domain, publish this TXT on the root domain:

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

What it does

include:spf.protection.outlook.com delegates to Microsoft's SPF, which authorizes current Exchange Online sending IPs. -all hard-fails everything else.

Where to publish

DNS host for your domain (Cloudflare, GoDaddy, Route53, Azure DNS). One TXT record on @ or root. Not in M365 admin. DNS only.

For full syntax rules, see zerohook.org/blog/spf-record-syntax-complete-reference.

M365 Plus ESP or SaaS (Common Templates)

1

M365 + Mailchimp on the same root domain (count lookups before publish):

v=spf1 include:spf.protection.outlook.com include:servers.mcsv.net -all
2

M365 + HubSpot marketing mail:

v=spf1 include:spf.protection.outlook.com include:spf.hubspotemail.net -all
3

M365 + SendGrid transactional:

v=spf1 include:spf.protection.outlook.com include:sendgrid.net -all
4

In Cloudflare: DNS → Add record → Type TXT → Name @ → Paste the single line → TTL Auto → Save. Remove any second TXT that starts with v=spf1. Two SPF records = PermError.

5

Validate at zerohook.org/spf-checker. Confirm lookup count stays at or below 10. If permerror, remove dead includes or move marketing to mail.yourdomain.com with its own SPF.

Frequently Asked Questions

Do I need a separate SPF for each subdomain?

Only if that subdomain sends mail with its own envelope-from. If Mailchimp sends as [email protected], publish SPF on mail.yourdomain.com, not only on the root.

Can I use ~all instead of -all on M365?

During a same-day migration test, maybe overnight. Production sending domains should use -all in 2026. Softfail weakens the signal receivers and auditors expect.

Microsoft says my domain is healthy. Why does Gmail still fail DMARC?

M365 domain health checks do not replace DMARC alignment on ESP mail. Enable DKIM in M365 (Admin → Domains → DKIM) and authenticate marketing tools separately.

Key takeaways

1

Standard M365-only SPF: v=spf1 include:spf.protection.outlook.com -all

2

Add one include per live ESP; remove old provider includes after migration.

3

One SPF TXT per domain; validate lookup count after every edit.

4

Pair SPF with DKIM and DMARC for Gmail and Microsoft receiver requirements.

Paste your TXT line at zerohook.org/spf-checker before you remove Google's include and wonder why nothing sends.

Share this analysis

Help others discover this content

About the author

ZeroHook Logo
ZeroHook Team
Security Analysts

The ZeroHook Team documents SPF and DKIM misconfigurations that still pass basic lookups but fail at Gmail and Microsoft 365.

Fix DNS before the next audit
Provider-specific copy-paste fixes for Cloudflare, Route53, GoDaddy, and more.
Start free scan