Back to blog
Threat Intel
Phishing Forensics

Microsoft 365's Hidden SPF Cost: The Nested Lookup Trap

That one `include` for Microsoft 365 in your SPF record costs you more DNS lookups than you think—here's the proof and the fix.

MailSleuth Research
Email Security Team
June 11, 20267 min read
An abstract illustration of a single SPF query triggering a chain reaction of multiple DNS lookups, threatening to break

You just added your new payment processor's SPF include. Everything looks good. A week later, your CFO's email to a key investor bounces. Then your CEO's. Panic sets in. You check the NDR and see a cryptic message: '550-5.7.26 SPF permanent error'. You haven't touched your record in a week, so what just happened? The culprit wasn't the new include. It was the one that's been there all along.

That innocuous line, `include:spf.protection.outlook.com`, is a time bomb. Many admins treat it as a single item on a checklist. In reality, it's a gateway to a chain of nested DNS queries that can silently push your domain over the hard 10-lookup limit mandated by RFC 7208.

This isn't a theoretical edge case. This is a primary cause of mission-critical email delivery failure for organizations using Microsoft 365 alongside other cloud services. Let's pull the thread and see how deep the rabbit hole goes.

The Anatomy of a Deceptive `include`

First, let's be precise about what an `include` mechanism does. It is not an alias. It's a directive. When a receiving mail server evaluates your SPF record and hits an `include:thirdparty.com`, it halts processing your record and starts a brand-new DNS lookup for the SPF record at `thirdparty.com`. That lookup, and any mechanisms inside of it, are evaluated as if they were part of your own record. Crucially, this initial jump costs one of your ten available DNS lookups.

This is where the trouble with `spf.protection.outlook.com` begins. You are not including a simple list of IP addresses. You are including a pointer to another, more complex SPF record managed entirely by Microsoft.

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

This single line in your TXT record seems clean. It represents your entire Microsoft 365 sending infrastructure. But what is actually inside that `spf.protection.outlook.com` record? That's what mail exchangers see, and that's what consumes your lookup budget.

Tracing the Lookup Chain Reaction

Let's trace the path a receiving mail server takes. The journey begins when the receiver performs a TXT query for your domain's SPF record. It finds your `include:spf.protection.outlook.com`. That's lookup #1.

Now, the server performs a second DNS query, this time for the TXT record of `spf.protection.outlook.com`. What it gets back is not a list of IPs, but more includes.

Down to spfa and spfb

As of this writing, the record for `spf.protection.outlook.com` looks something like this: `v=spf1 include:spfa.protection.outlook.com include:spfb.protection.outlook.com -all`. The receiver parses this from left to right. It sees `include:spfa.protection.outlook.com` and immediately triggers another DNS lookup. That's your second lookup consumed by the M365 chain.

It then queries `spfa.protection.outlook.com` and finds a list of `ip4` and `ip6` mechanisms. These IP ranges are the actual source addresses for Microsoft's outbound mail servers. Critically, `ip4` and `ip6` mechanisms do not consume a DNS lookup. But we're not done. The receiver continues parsing Microsoft's top-level SPF record and finds the next mechanism: `include:spfb.protection.outlook.com`. This triggers yet another DNS lookup. That's your third lookup spent.

Like the `spfa` record, `spfb.protection.outlook.com` also contains a list of IP addresses. Microsoft does this to keep the individual TXT records under the 255-character string limit for a single DNS response. They split their massive infrastructure across multiple SPF records and chain them together with includes. The operational impact on you is a multi-lookup tax just for using their service.

Calculating the True Cost of M365

So, let's tally the cost. The initial `include:spf.protection.outlook.com` is not one lookup. It's the beginning of a cascade. The record itself contains two more `include` mechanisms. This means that one line in your SPF record currently burns a total of three DNS lookups.

The 10-Lookup Limit is Not a Suggestion

RFC 7208 Section 4.6.4 is explicit: "SPF implementations MUST limit the number of mechanisms and modifiers that do DNS lookups to at most 10 per SPF check... If this limit is exceeded, the implementation MUST return a "permerror" result." This is not a 'maybe' or a 'should'. It's a 'MUST'.

A `permerror` (permanent error) signals a broken, misconfigured SPF record. From the perspective of a receiving server like Google Workspace or Proofpoint, a `permerror` is untrustworthy. Many systems will default to treating a `permerror` as equivalent to a hard `fail`. Your email gets rejected, and it has nothing to do with the sending IP address. Your entire domain's sending reputation is undermined by a technicality.

This lookup count can, and does, change without notice. If Microsoft adds `spfc.protection.outlook.com` to its primary SPF record tomorrow to support a new datacenter region, your baseline cost for M365 jumps from three lookups to four. Your perfectly valid record on Tuesday could be a `permerror` disaster on Wednesday.

Scenario: How One More Sender Breaks Everything

Consider a typical mid-sized company's SPF record. It likely contains includes for essential business tools.

v=spf1 include:spf.protection.outlook.com include:_spf.salesforce.com include:mail.zendesk.com include:sendgrid.net a mx -all — Example SPF record for a company using multiple SaaS platforms

Let's count them up. `include:spf.protection.outlook.com` is 3 lookups. Salesforce is 2. Zendesk is 2. SendGrid is 1. The `a` mechanism is 1 lookup (for your domain's A record), and the `mx` mechanism is 1 lookup (for your domain's MX records). Total so far: 3 + 2 + 2 + 1 + 1 + 1 = 10 lookups.

You are right on the edge. Now, Marketing wants to add a new service, `include:mktg.example.com`. You add it to the record. The moment you do, any receiver evaluating your SPF will now perform 11 DNS lookups and hit the `permerror` limit. All email from your domain, including from executives using Outlook, is now at high risk of being rejected because of a marketing tool you just authorized.

This is how deliverability incidents happen. It's not a big bang, but a slow creep of added services until an invisible limit is breached. This failure mode is particularly insidious because it won't affect *all* of your email. It only affects receivers that are strictly enforcing the SPF lookup limit, creating a confusing and inconsistent pattern of bounces that is difficult to troubleshoot without understanding the underlying mechanism.

The Remediation Playbook

Once you've confirmed you're at or near the 10-lookup limit, you can't just ignore it. You need a clear plan.

Aggressive Auditing and Pruning

The first and safest step is to audit every single mechanism in your record. For each `include`, ask: Is this service still in use? Is it mission-critical? Often, you'll find includes for services that were trialed but never purchased, or for divisions that have been divested. Removing even one unneeded `include` that resolves to two or three lookups can give you significant breathing room. Get ruthless. If you can't justify a sender's presence, cut it.

When to Consider Selective Flattening

SPF flattening is the process of replacing an `include` mechanism with the literal IP addresses it resolves to. For example, if `include:sendgrid.net` pointed to a record containing `ip4:1.2.3.4`, you would replace the `include` with the `ip4` mechanism directly in your own record. This saves one lookup.

This is a powerful technique but comes with a massive warning: do not do this for large, dynamic providers like Microsoft, Google, or Salesforce. Their IP ranges change frequently and without notice. The moment they add a new mail server and your flattened record doesn't have its IP, legitimate mail will start failing SPF checks. Only consider flattening for small, stable vendors where you have a direct relationship and can be notified of network changes. Even then, it creates technical debt that requires constant monitoring.

Some specialized DMARC and deliverability providers offer services that dynamically flatten your SPF record, automatically polling for upstream changes. These can be effective but transform a simple DNS record into a dependency on a third-party service.

The takeaway

The core issue isn't Microsoft. It's the inherent fragility of the SPF standard when confronted with the modern cloud-first enterprise. Every service you add to your digital supply chain, from HR to finance to marketing, wants a piece of your DNS. The `include:spf.protection.outlook.com` is often the largest single consumer of your lookup budget, making it the component that pushes an otherwise healthy record over the cliff.

Stop treating your SPF record as a static configuration file. It's a dynamic, high-stakes dependency chain. Regularly auditing your DNS lookups is not optional hygiene; it's a core component of modern email deliverability management. Using a tool to visualize your SPF chain, like the free analyzers available online or the continuous monitoring in a platform like MailSleuth.AI, can turn this invisible threat into a manageable risk.

#spf#microsoft-365#dmarc#email-security#dns
MailSleuth Research
Email Security Team

We dissect phishing campaigns and email infrastructure so you don't have to.