Skip to content
Start with 100 free verification credits
Qualisend
SPF setup guide

SPF, DKIM & DMARC for Microsoft 365.

Microsoft 365 (Exchange Online) doesn't authenticate your domain with a single wizard the way a hosted ESP does — it splits the job across two consoles. SPF is a genuine shared include (include:spf.protection.outlook.com) that you merge into the one SPF TXT record on your domain, and DKIM is two CNAME "selector" records you publish and then switch on in the Microsoft Defender portal. DMARC is a third, separate record that Microsoft never creates for you. Get all three aligned and Exchange Online sends fully authenticated as your own domain instead of leaning on the default onmicrosoft.com signature.

SPF include
Your DNSAdd the CNAME / TXT records
Microsoft 365Signs & sends as your domain
The inboxSPF · DKIM · DMARC pass

Why authenticate Microsoft 365?

Authenticating a Microsoft 365 domain decides whether your mail reaches the inbox, and M365 has a specific trap that quietly breaks DMARC. Since February 2024 Gmail and Yahoo require every bulk sender (roughly 5,000+ messages a day) to pass SPF, DKIM, and DMARC with alignment, and starting May 2025 Microsoft itself began enforcing the same on high-volume mail bound for Outlook.com/Hotmail/Live — so business mail landing in consumer Microsoft inboxes has to authenticate too. The catch unique to M365: out of the box, Exchange Online DKIM-signs your outbound mail with the tenant's onmicrosoft.com domain (d=contoso.onmicrosoft.com), which does not align with your custom From domain (contoso.com). SPF from Microsoft does align, so direct mail can scrape a DMARC pass on SPF alone — but the moment a message is forwarded (mailing lists, .forward rules, filtering gateways) SPF breaks, and because DKIM is signing as the wrong domain there is nothing left to carry DMARC. Setting up custom-domain DKIM is what closes that gap and lets the sending reputation you build accrue to your own domain.

The SPF reality for Microsoft 365

Microsoft 365 is a true "include" provider — unlike CNAME-delegation ESPs (Mailchimp, Klaviyo) or per-account senders (Amazon SES), there is one real shared include you add to your root SPF: include:spf.protection.outlook.com. Publish it inside a single SPF TXT record on the domain, e.g. v=spf1 include:spf.protection.outlook.com -all. Two things make M365's SPF unusually well-behaved. First, the include resolves to a flat record that contains only ip4:/ip6: ranges and its own -all — no nested includes — so it costs just ONE of your 10 SPF DNS lookups (a common myth says 2–3; the live record has no sub-includes). Second, because Exchange Online uses your own domain as the SMTP MAIL FROM (envelope/Return-Path) by default, SPF actually ALIGNS to your domain, so the M365 include contributes to a DMARC pass on its own — something Return-Path-owning ESPs can't do. Microsoft explicitly recommends the -all (hard fail) qualifier because it also expects you to run DKIM and DMARC. Two caveats: only sovereign/government clouds differ — GCC High and DoD use include:spf.protection.office365.us, and 21Vianet (China) uses include:spf.protection.partner.outlook.cn; and each sending subdomain needs its own SPF record (contoso.com's record does not cover marketing.contoso.com).

Step by step

In the Microsoft 365 admin center
  1. 1

    Confirm the domain and find its DNS records

    Sign in at admin.microsoft.com and go to Settings → Domains, select your domain, and open the DNS records tab. If you delegated your nameservers to Microsoft, it may already have published SPF and the MX (yourdomain-com.mail.protection.outlook.com). If your DNS lives at a registrar/host, note that M365 has no SPF or DMARC controls here — you'll add those records at your DNS host yourself.

In your DNS
  1. 2

    Publish or merge the SPF record

    At your DNS host create ONE TXT record on the root (host @): v=spf1 include:spf.protection.outlook.com -all. If a v=spf1 record already exists (Google Workspace, a marketing tool, etc.), merge the include into that single record — never add a second SPF TXT. Microsoft recommends ending with -all (hard fail). GCC High/DoD use spf.protection.office365.us; 21Vianet uses spf.protection.partner.outlook.cn.

In the Defender portal
  1. 3

    Open the DKIM tab

    Custom DKIM is NOT in the M365 admin center. Go to security.microsoft.com → Email & collaboration → Policies & rules → Threat policies → Email authentication settings, then select the DKIM tab.

  2. 4

    Reveal the two CNAME values

    Click your custom domain. A domain that was never set up shows Status = NoDKIMKeys and the toggle Disabled. Slide the toggle to Enable — because the CNAMEs don't exist yet it opens a 'Client error' dialog and the Status changes to CnameMissing. That is expected, not a failure: the 'Publish CNAMEs' section now surfaces the exact selector1 and selector2 CNAME targets. Copy them (or run Get-DkimSigningConfig -Identity yourdomain.com | Format-List Selector1CNAME,Selector2CNAME in Exchange Online PowerShell).

In your DNS
  1. 5

    Add the two DKIM selector CNAMEs

    Create selector1._domainkey and selector2._domainkey as CNAME records pointing to the exact targets the portal gave you. Newer domains (the format Microsoft introduced in May 2025) get targets like selector1-<domain-with-dashes>._domainkey.<tenant>.<char>-v1.dkim.mail.microsoft (the <char>, e.g. n or r, is a partition character Microsoft assigns); domains set up before then get selector1-<domain-with-dashes>._domainkey.<tenant>.onmicrosoft.com. Use whichever format the portal shows — the two formats can't be mixed on one selector. Don't change them to TXT.

In the Defender portal
  1. 6

    Switch DKIM to Enabled

    After the CNAMEs propagate (usually minutes, up to 48 hours), return to the DKIM tab, select the domain, and slide the toggle to Enable again. Status flips to Valid and 'Rotate DKIM keys' becomes available. From now on M365 signs with d=yourdomain.com instead of the onmicrosoft.com default, so DKIM aligns.

In your DNS
  1. 7

    Add the DMARC record

    M365 doesn't create DMARC. Add a TXT record at host _dmarc: v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com. Start at p=none — Microsoft's 'take no action' monitoring mode — so nothing is affected while you confirm both SPF and DKIM align, then tighten later.

Verify
  1. 8

    Send a test and read the headers

    From a mailbox on the domain, email yourself at Gmail, open the message and choose ⋮ → Show original. You want SPF: PASS showing your domain, DKIM: PASS with d=yourdomain.com (NOT onmicrosoft.com), and DMARC: PASS. Then confirm every record resolves with a domain health check.

Records to add

Microsoft 365 generates the exact values in its setup wizard — these show the shape of what you'll add at your DNS host.

TypeHostValue
TXT@v=spf1 include:spf.protection.outlook.com -allRoot SPF — keep exactly ONE SPF record; merge this include if you already have a v=spf1 record. Costs ~1 DNS lookup.
CNAMEselector1._domainkeyselector1-contoso-com._domainkey.contoso.n-v1.dkim.mail.microsoftDKIM key 1 (auto-rotated). Illustrative — copy the exact target from the Defender portal; domains created before May 2025 end in .onmicrosoft.com instead of .n-v1.dkim.mail.microsoft.
CNAMEselector2._domainkeyselector2-contoso-com._domainkey.contoso.n-v1.dkim.mail.microsoftDKIM key 2 (the second selector lets Microsoft rotate keys). Illustrative — use the exact value from the portal.
TXT_dmarcv=DMARC1; p=none; rua=mailto:dmarc@yourdomain.comYou add this yourself — M365 never creates it. One per domain; start at p=none.
MX@contoso-com.mail.protection.outlook.comRoutes inbound mail to Exchange Online (priority 0). Not an authentication record, but part of M365 setup; dots in your domain become hyphens.

Keep exactly one SPF (v=spf1) TXT record on your root domain — merge every sender into it. Two SPF records is itself an error.

The 10-lookup budget

SPF is capped at a hard 10 DNS lookups — go over and it returns a permerror and stops validating everywhere. Here's what Microsoft 365's setup costs against that budget.

SPF 10-lookup budget1 used · 9 free

Microsoft 365 adds 1 of your 10 lookups; ip4: and ip6: mechanisms are free.

DKIM

DKIM in Microsoft 365 is the part people get wrong, because M365 is 'already signing' mail before you do anything — just with the wrong domain. By default Exchange Online DKIM-signs outbound mail using your tenant's initial onmicrosoft.com domain (d=contoso.onmicrosoft.com). That signature is valid, but it does not align with your custom From domain, so it does nothing for DMARC on contoso.com. To fix that you enable custom-domain DKIM: two CNAME records, selector1._domainkey and selector2._domainkey, that delegate the public keys back to Microsoft. Because they're CNAMEs (not TXT records you paste), Microsoft holds the private keys and uses the two selectors to rotate keys automatically without you ever touching DNS again. The target format changed in May 2025: newer custom domains get selector1-<domain-with-dashes>._domainkey.<tenant>.<char>-v1.dkim.mail.microsoft (the <char>, e.g. n or r, is a partition character Microsoft assigns), while domains set up before then still use selector1-<domain-with-dashes>._domainkey.<tenant>.onmicrosoft.com — the portal (or Get-DkimSigningConfig in Exchange Online PowerShell) shows exactly which one your tenant is assigned, and the two formats can't coexist for a selector. Workflow: reveal the CNAMEs in the Defender portal (Email authentication settings → DKIM), publish both at your DNS host, wait for propagation, then flip the DKIM toggle for the domain to Enabled so Status shows Valid. Keys default to 1024-bit; 2048-bit is available via New-DkimSigningConfig (with -KeySize 2048). Only after the toggle is Enabled does M365 sign with d=yourdomain.com and DKIM start aligning.

DMARC

DMARC is a separate policy TXT record on your domain that Microsoft 365 does not create — you add it at your DNS host. Publish it at _dmarc.yourdomain.com starting with v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com. p=none is Microsoft's recommended 'take no action' monitoring mode: it changes nothing about delivery while you watch the aggregate (rua) reports to confirm M365 (and any other senders) pass SPF and DKIM aligned to your domain. Microsoft's own guidance is to get DKIM signing and DMARC in monitoring mode up quickly, then ramp the policy — tighten to p=quarantine, then p=reject, once alignment is consistent. Keep just one _dmarc record for the whole organizational domain; subdomains inherit the parent policy automatically (you can override a specific subdomain with its own _dmarc record or the sp= tag). Because M365's SPF aligns and, once you've set up custom DKIM, DKIM aligns too, a properly configured M365 domain passes DMARC on both mechanisms — the resilient setup that survives forwarding.

Check it actually worked

Don't trust the Defender portal's 'Valid' badge alone — confirm it on a real message. Send yourself a test from a mailbox on the domain, open it in Gmail, and choose ⋮ → Show original: you want SPF: PASS, DKIM: PASS with d=yourdomain.com (the tell-tale failure is d=yourtenant.onmicrosoft.com, which means custom DKIM isn't enabled yet), and DMARC: PASS. In the Defender portal the DKIM tab should show Status = Valid and Toggle = Enabled for the domain. Then run your domain through Qualisend's domain health check to confirm the SPF, both DKIM selector CNAMEs, and the DMARC record all resolve cleanly, and once DMARC aggregate reports start arriving, drop one into the DMARC report analyzer — Outlook.com / Exchange Online should appear as an aligned, passing source.

Common gotchas

  • Coverage

    The #1 M365 trap: until you enable custom-domain DKIM, mail is signed as d=yourtenant.onmicrosoft.com, which does NOT align — so DMARC gets no help from DKIM and breaks the moment a message is forwarded. SPF-only is not enough.

  • DNS setup

    The 'Client error' dialog / CnameMissing status you get when you first slide the DKIM toggle to Enable is expected, not a bug — it's how the portal reveals the CNAME values. Publish the two CNAMEs, then come back and toggle Enable again.

  • DNS setup

    DKIM CNAME targets changed in May 2025: custom domains set up since then point to <tenant>.<char>-v1.dkim.mail.microsoft, older ones to <tenant>.onmicrosoft.com. Copy the exact target from the Defender portal (or Get-DkimSigningConfig) — the old and new formats can't be mixed on the same selector.

  • Breaks auth

    Keep exactly ONE SPF TXT record on the domain. If you already send via Google Workspace, SendGrid, etc., merge include:spf.protection.outlook.com into that single record — two SPF TXT records is itself a PermError.

  • Coverage

    GoDaddy- or IONOS-provisioned M365 often ships a default SPF of include:secureserver.net, which does NOT authorize Exchange Online mailboxes. It must resolve to include:spf.protection.outlook.com.

  • DNS setup

    M365 DKIM records are CNAMEs, so if your DNS is behind Cloudflare set each selector record to 'DNS only' (grey cloud) — an orange-cloud proxied CNAME won't resolve to the Microsoft host and DKIM enable fails.

  • DNS setup

    Watch the SPF syntax mistakes Microsoft calls out: no trailing period (include:spf.protection.outlook.com. is wrong), a colon not an equals sign after 'include', and no space after the colon. Many registrars also auto-append your domain to CNAME/host fields, doubling it.

  • Coverage

    Every sending subdomain needs its own SPF (and its own DKIM). The record on contoso.com does not cover marketing.contoso.com — bulk/marketing tools sending from a subdomain need SPF, DKIM, and typically their own DMARC handling there.

Build your SPF record

Microsoft 365 is pre-selected below. Add any other platforms you send through, then publish the single merged record.

1

Sending sources

Search for each platform you send email through and tick it.

Selected
Guide →
2

This domain's own servers

Authorize the domain itself, if it sends mail directly (not through a platform above).

3

Other senders & IPs

Anything not in the list — another provider's SPF host, or specific IP addresses.

We add the include: prefix — enter the hostname your provider documents.

4

Policy for everyone else

What receivers should do with mail from any server not listed above (the all mechanism).

Your SPF record1/10 DNS lookups
v=spf1 include:spf.protection.outlook.com ~all
  • Publish it as a TXT record at your root domain — host @ (the bare domain), value the full string above.
  • Keep only one SPF record per domain. Merge every sending source into this single line — a second TXT record starting v=spf1 makes both invalid.
  • Stay at or under 10 DNS lookups. Each include:, a and mx counts, and an include can trigger more lookups inside itself — ip4: and ip6: are free.

Authentication published? The next step is sending to a clean, verified list.

Verify a list

Microsoft 365 SPF — FAQ

Related reading

Once it's published, confirm everything resolves with the domain health check, then read who's sending as you with the DMARC report analyzer. Browse all sending sources in the generator. Authentication is only half of deliverability, though — a listed sending IP or domain still lands you in spam no matter how clean your SPF is, so it's worth watching the blacklists with blacklist monitoring.

Authenticated — now keep the list clean

Passing SPF, DKIM, and DMARC gets you to the inbox; a clean list keeps you there. Verify yours — start free with 100 credits, no card required.

Start verifying