Microsoft 365 · Cloudflare · Full setup
Microsoft 365 on Cloudflare: complete email authentication in one pass
Before anything: the Cloudflare pre-check
If Cloudflare Email Routing is enabled on this domain, stop and turn it off first. Cloudflare's documentation is blunt: Email Routing “cannot be used with external mail servers” — it installs its own MX records (to Cloudflare), its own SPF include, and its own DKIM record at cf2024-1._domainkey (not a Microsoft selector — don't confuse them). Turning Routing off removes its managed records. With Routing on, every record below fights a tenant you forgot you had.
The target state — every record
| Record | Name | Value | Notes |
|---|---|---|---|
| TXT (verify) | @ | MS=msXXXXXXXX (your tenant's) | Proves ownership; deletable after verification |
| MX | @ | <domain-key>.mail.protection.outlook.com | The ONLY MX — delete every other. (Microsoft's Cloudflare page prints priority 1; Cloudflare's table prints 0; for a sole MX the number is immaterial) |
| TXT (SPF) | @ | v=spf1 include:spf.protection.outlook.com -all | Exactly one SPF record; the include costs 1 lookup term today |
| CNAME | autodiscover | autodiscover.outlook.com | Client configuration; keep DNS-only (Microsoft's page is silent on proxy here — Cloudflare semantics say DNS-only, flagged honestly) |
| CNAME (DKIM 1) | selector1._domainkey | Your value from the Defender portal | DNS only at Cloudflare; TTL 1 hour (our DKIM guide covers the traps) |
| CNAME (DKIM 2) | selector2._domainkey | Your value from the Defender portal | Published from day one — it's the rotation standby (Article #39) |
| TXT (DMARC) | _dmarc | v=DMARC1; p=none; rua=mailto:you@yourdomain | Yours alone to publish — start at p=none, climb per Article #4 |
Optional, only if you use them: Teams — SRV _sip._tls → sipfed.online.lync.com:443; SRV _sipfederationtls._tcp → :5061; CNAMEs sip, lyncdiscover. Intune — CNAMEs enterpriseregistration, enterpriseenrollment. MDM/legacy msoid records from old setups: Microsoft's guidance to remove them was read on its government-cloud page — treat removal as the direction, verified per tenant. | |||
Path A — automatic (Domain Connect)
- M365 admin center → Settings → Domains → (your domain) → ⋯ → Manage DNS → Continue → Add DNS records. Cloudflare is a listed Domain Connect partner; you're handed to a Cloudflare login and an Authorize consent, landing on “Your domain setup for Microsoft 365 is complete.” (Microsoft frames this for domains “not yet set up with another email service provider.”)
- Know its limits: Microsoft publishes no record list for what the automation writes — judge it by the readbacks in §Verify, not by the success banner. And it changes nothing about the two omissions: DKIM still waits in Defender; DMARC still waits for you.
Path B — manual ladder (six rungs)
- Verify: publish the
MS=TXT; verify in the admin center; the TXT may then be deleted. - MX: replace ALL MX records with the single Microsoft target.
- SPF: one TXT as tabled. Adding other senders later? Merge their includes into this record (Article #18's rules; watch the lookup budget, Article #3).
- DKIM: Defender portal → create keys → copy YOUR two CNAME values → publish at Cloudflare, DNS only, TTL 1 hour (Microsoft's Auto-TTL example conflicts with its own troubleshooter's 3600 floor — 1 hour satisfies both, Pack #10) → enable signing in Defender. Full traps-and-all walkthrough: Article #10.
- DMARC: publish the tabled record; use Cloudflare's DMARC Management or your reports (Article #36) to watch sources; climb p per Article #4.
- Autodiscover CNAME as tabled (+ optional Teams/Intune rows if used).
Verify (the suite, not a vibe)
- Readbacks: public lookups return exactly the table — one MX, one SPF, both selector CNAMEs (as CNAMEs, not flattened/proxied addresses), one _dmarc.
- Defender done-state: DKIM tab shows the domain Enabled / signing (the only DKIM completion check — a wizard's checkbox is not).
- Header test: send to an external mailbox; Authentication-Results shows
spf=pass,dkim=pass(d= your domain),dmarc=pass. Microsoft's own Message Header Analyzer and Remote Connectivity Analyzer are the vendor's instruments for this. - 48-hour rule: Microsoft's troubleshooters treat persisting errors past ~48 hours as wrong values, not slow DNS (Cloudflare publishes in minutes). Re-check the table before re-waiting.
Traps
| Trap | Reality |
|---|---|
| “Setup complete” = authenticated | Domain Connect's banner covers verification + core records. DKIM (Defender) and DMARC (you) are separate acts — §1's warning. |
| Email Routing still on | Its MX set outranks your intentions; mail routes to Cloudflare while you debug Microsoft. Triple-sourced from Cloudflare's docs — pre-check first. |
| Proxied DKIM CNAMEs | Microsoft warns twice in its own Cloudflare example: proxy on = lookups return Cloudflare IPs, verification fails. DNS only, both selectors (Article #10). |
| A “helpful” second MX for backup | The Microsoft MX must be the sole MX. A leftover registrar/Google MX splits inbound mail between two providers — some mailboxes simply never receive some mail. |
FAQ
We migrated from Google — old records everywhere.
Replace, don't accumulate: Google's MX set and SPF include come out as Microsoft's go in (two live MX sets = split delivery; two SPF records = PermError, Article #18). DKIM selectors don't collide (Google's is a TXT at its own selector name) but stale records are tomorrow's confusion — remove them once Microsoft's suite verifies.
Do I need the Teams/Intune records for email to work?
No — they're service records for those products only. Email stands on the seven core rows.
Where does the rua mail go?
Wherever you point it — a mailbox you control or a report service (Article #36). An unread rua is a p=none that never climbs: assign it an owner.
Sources
Microsoft Learn — Cloudflare provider records page (record set, Domain Connect flow) · Defender DKIM article (portal keys, Cloudflare example, TTL troubleshooter) · Defender DMARC article (record syntax; direct fetch 403'd in research — syntax corroborated via search index + Pack #9, flagged) · Cloudflare — Email Routing documentation & troubleshooting (“cannot use with external mail servers”; managed-record removal; cf2024-1 selector) · Packs #1/#3/#9/#10 (enforcement, lookup costs, GoDaddy sibling, DKIM depth).
Did this guide work for you?
Your reaction tells us whether this guide solved the problem it promised to solve.