Microsoft 365 · DKIM · Cloudflare DNS
Turn on DKIM for Microsoft 365 — when your DNS is on Cloudflare
On Cloudflare this fix is lost in the proxy toggle, not in the values. A proxied selector CNAME answers Microsoft's verifier with Cloudflare's IP addresses instead of the CNAME target — Microsoft prints that caution twice in its own Cloudflare example.
The fast answer
- Defender portal (
security.microsoft.com) → Email authentication settings → DKIM tab → your domain → slide to Enabled → the “Client error” dialog is expected → OK → status CnameMissing. - Open the domain's flyout → Publish CNAMEs → copy your two targets (per-tenant; since May 2025 they carry an unguessable partition character under
dkim.mail.microsoft— copy from nowhere else). - Cloudflare: add both CNAMEs with Proxy status: DNS only and TTL: 1 hour (table below).
- Back in the flyout: switch on “Sign messages for this domain with DKIM signatures.”
The Cloudflare records — fields, exactly (Microsoft's own example)
| Cloudflare field | Record 1 | Record 2 |
|---|---|---|
| Type | CNAME | CNAME |
| Name | selector1._domainkey | selector2._domainkey |
| Target | The exact value from your portal's Publish CNAMEs flyout. (Microsoft's registrar table for Cloudflare: no trailing dot needed; Cloudflare appends your domain to names automatically.) | |
| Proxy status | DNS only — grey cloud. Non-negotiable; see the traps table. | |
| TTL | 1 hour, set explicitly. Microsoft's example also blesses “Auto,” but its troubleshooter asks for ≥3600s and Auto is ~300s — one hour is the value both Microsoft documents agree on. | |
The two Cloudflare traps — and which one your plan can even have
| Trap | Who can fall in | What happens / the fix |
|---|---|---|
| Proxied CNAME | Everyone — check every record you add | Lookups return Cloudflare IPs instead of the target; verification fails on perfect records. Also note: proxied records are always flattened by Cloudflare. Fix: Proxy status → DNS only on both selectors. |
| CNAME flattening | Paid plans only | Flatten-all (DNS settings) and per-record Flatten are paid features; Free-plan apex flattening cannot touch selector1._domainkey. Cloudflare's own words: flattening “may cause the verification to fail since the CNAME record itself will not be returned directly.” Paid-plan fix: selectors unflattened (and unproxied). |
Most guides shout “disable flattening!” at every Cloudflare user. For Free-plan readers that instruction is a wild goose chase — your plan cannot flatten these records; your trap is the proxy toggle. Paid-plan readers: you have both traps; DNS-only disarms the first and the flatten settings the second.
Neighbours in your Cloudflare account that matter
| Feature | Relation to this fix |
|---|---|
| Email Routing | Can genuinely conflict — but through your MX records, which Cloudflare itself says Email Routing manages and which “may conflict” with external mail servers. If your mail is Microsoft 365, Email Routing should not be your MX story. Its own DKIM record lives at cf2024-1._domainkey — a different selector, no collision with Microsoft's selectors. Do not delete it in a panic; resolve the MX question, not the DKIM one. |
| DMARC Management | A complement, not a conflict: reporting for your one DMARC record. It never touches DKIM. Fine to use; never a substitute for the steps above. |
Prove it worked
- Read back like a verifier: a DNS lookup for
selector1._domainkey.yourdomainmust return a CNAME naming your tenant's Microsoft target. If it returns A/AAAA addresses (Cloudflare's), the record is proxied or flattened — the dashboard will look identical either way, which is why the read-back, not the screenshot, is the proof. - Defender portal: status shows signing enabled, CnameMissing cleared (allow up to Microsoft's documented 48-hour ceiling; correct records usually clear far sooner).
- A real message: headers via Microsoft's Message Header Analyzer show
dkim=passwithheader.d= your domain. Watch fordkim=temperror— Microsoft ties it to short probe/TTL behaviour; the explicit 1-hour TTL above is your insurance.
FAQ — the issues behind this problem
I'm on the Free plan and a guide told me to disable flattening. I can't find the setting.
It isn't there — flatten-all and per-record flattening are paid-plan features, and Free's apex-only flattening can't reach your selector names. On Free, spend the suspicion on the proxy toggle instead; it's the trap your plan actually has.
Both CNAMEs are DNS-only and it still says CnameMissing.
Then work the shared list from our GoDaddy edition: values copied from a pre-May-2025 screenshot (wrong format now), a TXT record squatting where a CNAME belongs, a doubled name — then honest propagation time.
Does turning on DKIM change my SPF or DMARC?
No record changes: SPF already names Microsoft (direct tenants), and DMARC simply gains a second, aligned way to pass. If you haven't set DMARC yet, our rollout guide is the next hour well spent.
Sources
Microsoft Learn — DKIM for your custom domain (including its Cloudflare example and registrar table: Cloudflare — trailing dot No, auto-append Yes, must disable proxy), DKIM troubleshooter (TTL ≥3600, temperror) · Cloudflare Developers — proxy status, CNAME flattening overview and settings, email troubleshooting (DKIM + flattening), Email Routing conflict documentation.
Did this fix work for you?
Your reaction tells us whether this guide solved the problem it promised to solve.