What this check looks at
Checks each custom domain publishes exactly one SPF record that ends in a hard or soft fail.
SPF (Sender Policy Framework) is a single TXT record on a domain, starting v=spf1, that lists the servers allowed to send mail for that domain and ends with an all mechanism telling receivers what to do with everything else: -all (fail), ~all (soft fail), ?all (neutral) or +all (pass anything). Microsoft 365 does not publish it for you; the admin centre shows the record it expects, and someone must add it at the DNS host, including every other service that sends as the domain.
The check reads public DNS for every custom domain, including domains that never send mail. It fails a domain with no SPF record, with more than one (which makes SPF return a permanent error for every message), or whose record ends in +all, ?all or no all mechanism. It warns when a domain whose mail goes through Microsoft 365 does not include Microsoft 365 (include:spf.protection.outlook.com), and when the record ends in ~all while the domain’s DMARC policy is not quarantine or reject. The evidence gives each domain’s current record and the record to publish.
Without a strict SPF record, anyone can send mail using the domain and receivers have no basis to reject it; with two records, even genuine mail fails. Parked domains are the easiest to abuse because nobody watches them: phishing from a firm’s old trading name or a variant it owns is more convincing than from a random domain.
Why it matters
Without a strict SPF record, anyone can send email that appears to come from the organisation, and receiving servers have no basis to reject it. It is the first thing a phishing campaign against your customers or suppliers relies on.
A common UK case: criminals send invoices apparently from a building firm’s domain to its customers, with new bank details. Without SPF and an enforcing DMARC policy many receiving systems deliver them, and customers who pay the fraudster may look to the firm to make it good. Even where the money lost is not the firm’s own, the damage to trust and the time spent with customers and their banks are real.
SPF also decides whether genuine mail arrives. Domains without a correct record see more of their invoices, quotes and replies junked, and Google and Yahoo now require SPF or DKIM from every sender, and SPF, DKIM and DMARC from bulk senders. A missing include for the marketing or invoicing platform is a common reason customers say they never received something.
The CIS Microsoft 365 Foundations Benchmark (2.1.8) asks for SPF records on all Exchange domains, CISA SCuBA (MS.EXO.2.2) asks for an SPF policy that fails unapproved senders, and CIS Controls v8 9.5 asks for DMARC, which builds on SPF. The NCSC’s email security and anti-spoofing guidance recommends SPF, DKIM and DMARC for every domain, including those that do not send mail.
How to fix it
Where: Your DNS provider; Microsoft 365 admin centre → Settings → Domains shows the expected record
Before you start
- List every service that sends mail as the domain (Microsoft 365, marketing tools, CRM, website forms) and include each in the one SPF record.
- Keep under 10 DNS lookups in the record.
Step by step
- Read the current and proposed records. Open this finding’s evidence and note, for each domain, the current SPF record and the proposed one. Check the live value with Resolve-DnsName -Name contoso.com -Type TXT in PowerShell (or nslookup -type=txt contoso.com) and look for every string beginning v=spf1; more than one means they must be merged into one.
- List every service that sends as the domain. Ask the client, and check recent message headers and any DMARC reports, for services sending as the domain besides Microsoft 365: marketing platforms, CRM, helpdesk, accounting and invoicing systems, website contact forms. Each provider documents the include or IP address to add. In the Microsoft 365 admin centre, Settings > Domains > the domain > DNS records shows the SPF value Microsoft expects.
- Build one record within the lookup limit. Combine everything into a single record, for example v=spf1 include:spf.protection.outlook.com include:<other provider> -all. SPF allows at most 10 DNS lookups in total (each include, a, mx, exists and redirect counts, including those nested inside the includes), so remove services no longer used, prefer ip4: entries for fixed addresses and never use ptr. An online SPF checker will count the lookups for you.
- Publish it at the DNS host. At the domain’s DNS host, edit the existing TXT record at the root (shown as @ or the bare domain) rather than adding another, and delete any second v=spf1 record. A TTL of an hour or less makes later corrections quicker.
- Lock down the domains that never send mail. For each parked or non-sending custom domain, publish the TXT record v=spf1 -all at the root, which says no server may send as it. Give the same domains the DMARC record v=DMARC1; p=reject, which the DMARC finding covers.
- Choose between -all and ~all. End the record in -all once every legitimate sender is included. The check accepts ~all only where the domain’s DMARC policy is quarantine or reject, because DMARC is then what tells receivers to act; CISA’s baseline asks for -all whatever DMARC says, so move to -all as soon as the senders are complete.
- Confirm the record and a real message. Once the change has propagated, run Resolve-DnsName again and confirm exactly one v=spf1 record with the expected ending. Send a message from the domain to an external mailbox such as Gmail, open the original headers and check Authentication-Results shows spf=pass. The next assessment shows each domain passing.
What users will notice
None if every sender is included. A missing sender’s mail may go to spam.
How to confirm it worked
Look up the TXT record for the domain (for example with an online SPF checker): exactly one record starting v=spf1 and ending -all or ~all.
Frameworks and controls
This check maps to controls in 12 frameworks. Passing it is evidence that the setting is in place, not a certification against any of them.
| Framework | Control |
|---|---|
| NCSC CAF | B4.b Secure configuration |
| DSPT | Standard 9: IT protection |
| NIS2 | Art. 21(2)(g) Basic cyber hygiene practices and training |
| Zero Trust | Applications |
| SOC 2 | CC6.6 Protection against threats from outside the system boundaries |
| PCI DSS 4.0.1 | 5.4.1 Personnel are protected against phishing attacks |
| ISO 27001:2022 | A.5.14 Information transfer |
| CISA SCuBA | MS.EXO.2.2v3 SPF fails every sender not approved, for each domain |
| CIS M365 | 2.1.8 Ensure that SPF records are published for all Exchange Domains |
| CIS Controls v8.1 | 9.5 Implement DMARC (IG2) |
| NIST CSF 2.0 | PR.PS-01: Configuration management practices are established and applied |
| NCSC 10 Steps | Architecture and configuration |
The framework mappings were last checked against the published standards in October 2026.
Microsoft’s documentation
- Set up SPF to help prevent spoofing (Microsoft Learn)