Microsoft 365

SPF Record Too Long: Fix the 10-Lookup Limit with Microsoft 365

Fix SPF permerror caused by more than 10 DNS lookups. Count lookups, remove unused includes, move senders to subdomains and flatten only where it is safe, without breaking Microsoft 365 mail.

By EpiFive Editorial TeamReviewed/updated 10 min readHow we check articles
On this page

An SPF record fails with a permanent error when evaluating it needs more than 10 DNS lookups, and the message may be rejected with "The message exceeded the hop count" or "The message required too many lookups". To fix it, count the lookups your record really causes, delete includes for services you no longer use, move third-party senders to subdomains that have their own SPF record, and replace an include with ip4: ranges only for vendors whose addresses are stable. Do not flatten include:spf.protection.outlook.com.

Who this is for and what you will have at the end

This guide is for administrators who use Microsoft 365 for mail from a custom domain and have added marketing tools, ticketing systems, CRMs or on-premises servers to the same SPF record, and who now see SPF permerrors or bounces.

At the end you will have:

  • A clear picture of what counts toward the limit and what does not.
  • A method to count lookups, including nested ones.
  • A ranked list of fixes, from least to most risky.
  • A corrected record, and a way to verify it.

What the 10-lookup limit is

SPF is defined in RFC 7208. Section 4.6.4 requires that implementations cap the counted terms in an SPF evaluation at 10, and that exceeding the cap produces a permerror. Per section 2.6.7, a permerror means the published records could not be correctly interpreted and DNS operator intervention is needed.

The terms that count are:

Counts toward 10Does not count
include:ip4:
aip6:
mxall
ptr
exists
redirect modifier

Microsoft's own page lists include:, a, mx, exists and redirect as counting, and ip4:, ip6: and all as not counting. The RFC also counts ptr, so use the RFC as the authority. The RFC adds two details:

  • Each MX record queried counts toward the 10, and evaluating one MX record must not query more than 10 address records, or the mx mechanism returns permerror.
  • Implementations should limit void lookups (answers that are empty or NXDOMAIN) to 2. Exceeding it produces a permerror, so a stale include: pointing to a domain that no longer has an SPF record can cause trouble on its own.

Nested includes are the usual culprit

Each include: costs at least one lookup, and the record it points to is evaluated too. Microsoft's example: an include: that points to another SPF record containing three more include: statements adds four lookups in total. So having fewer than 10 include: statements does not guarantee fewer than 10 lookups.

Why it fails only sometimes

Receivers evaluate sources from left to right and stop when the sending source matches. An SPF record that could cause more than 10 lookups can still pass for sources listed early, and fail for sources listed late. Microsoft notes that some destinations may not go deep enough in the record to hit the error. That is why the symptom looks random: one sender's mail works, another's bounces.

Prerequisites

  • Access to the DNS host for your domain. Microsoft 365 has no admin portal or PowerShell cmdlet for managing SPF records, so you edit the TXT record at your registrar or DNS hosting service.
  • A list of every service that sends mail as your domain. If you do not have one, start with the bounce messages, message headers and, if you have it, DMARC reports. Microsoft recommends a DMARC reporting service for identifying email sources and SPF failures.
  • A copy of the current SPF record, so you can roll back.

Step 1: Read the current record

Query the TXT record for your domain. On Windows PowerShell:

Resolve-DnsName -Name contoso.com -Type TXT | Where-Object { $_.Strings -match '^v=spf1' } | Select-Object -ExpandProperty Strings

On Linux or macOS:

dig +short TXT contoso.com

Confirm there is exactly one record that starts with v=spf1. Multiple SPF TXT records for the same domain cause SPF to return permerror, because the receiver cannot decide which to evaluate. If you find two, merge them into one.

A typical over-grown record looks like this (the includes are placeholders):

v=spf1 include:spf.protection.outlook.com include:mail.crm.example include:send.marketing.example include:tickets.support.example include:old.newsletter.example mx a ip4:203.0.113.10 -all

Step 2: Count the lookups

Walk the record and count each counted term, then open every include: target and count the terms inside it, and so on. Microsoft's page says some free online tools show your SPF record and even calculate the lookups required. Use one to confirm your manual count, but check the result against the rules above because tools differ on ptr and void lookups.

A worksheet helps:

TermLookups at this levelNested lookupsTotal
include:spf.protection.outlook.com1Count what its record contains
include:mail.crm.example1Count
mx1 (plus each MX record queried)
a1
ip4:203.0.113.1000

If the total is above 10, continue.

Step 3: Apply the fixes in order

Fix 1: Remove what you no longer use

Delete includes for services that no longer send mail as your domain. Old newsletter tools, trial products and decommissioned ticketing systems are the common ones. This costs nothing and cannot break current mail, provided your list of senders is accurate.

Also check for includes that no longer resolve. Microsoft warns that if an include: domain does not resolve or has no SPF record, SPF validation returns permerror and messages might be rejected. Verify each include by querying the TXT record of the referenced domain.

Fix 2: Remove mx and a if they are not needed

Each costs a lookup, and mx costs one for each MX record it queries. If your mail is sent only by Microsoft 365 and listed services, you probably do not need them. Check first, because an on-premises server that sends mail may rely on them. If you do need an on-premises server, it is usually cheaper to list its public address with ip4:, which does not count.

Fix 3: Move third-party services to subdomains

Microsoft recommends using a subdomain such as marketing.contoso.com for email services that you do not directly control, so problems with those senders do not affect the reputation of your main domain. It is also the best fix for the lookup limit, because each subdomain has its own SPF record and its own budget of 10 lookups.

The steps are:

  1. Choose a subdomain for the service.
  2. Configure the service to send from that subdomain, following its documentation.
  3. Publish an SPF TXT record for the subdomain.
  4. Remove the service's include from the main domain's record.

Following Microsoft's example for a bulk mailing service:

contoso.com            TXT  "v=spf1 ip4:192.0.2.10 include:spf.protection.outlook.com -all"
marketing.contoso.com  TXT  "v=spf1 include:servers.adatum.com include:spf.protection.outlook.com -all"

Remember that the record for contoso.com does not cover marketing.contoso.com, so every subdomain that sends mail needs its own SPF TXT record. Only include spf.protection.outlook.com in the subdomain's record if that subdomain also sends from Microsoft 365.

Fix 4: Consolidate services

If two tools do the same job, retire one. Fewer vendors means fewer includes and fewer things to monitor.

Fix 5: Replace an include with IP ranges (flattening), carefully

SPF flattening replaces include: with the resolved IP addresses, which cost nothing because ip4: and ip6: do not count. Microsoft's guidance:

  • Appropriate for vendors with stable, documented IP ranges, services that rarely change addresses, and when you are at or over the limit and the other fixes are not feasible.
  • Do not flatten Microsoft 365 (include:spf.protection.outlook.com), because its sending infrastructure uses dynamic IP addresses that change frequently. Also do not flatten any cloud service with dynamic or frequently changing addresses.
  • If you flatten, document what you replaced and when, monitor vendor documentation for address changes, review the flattened entries at least quarterly and test SPF after each change.

Non-Microsoft flattening services can automate tracking vendor changes if manual maintenance is impractical. Evaluate them against your own risk tolerance, because they place a third party in control of part of your DNS.

Step 4: Check the syntax

A record can fail even with few lookups if it is malformed. Microsoft lists these common mistakes:

IncorrectProblemCorrect
v=spf1 include:spf.protection.outlook.com. -allTrailing period after the domainv=spf1 include:spf.protection.outlook.com -all
v=spf1 include=spf.protection.outlook.com -allEquals sign instead of colonv=spf1 include:spf.protection.outlook.com -all
v=spf1 include: spf.protection.outlook.com -allSpace after the colonv=spf1 include:spf.protection.outlook.com -all

The minimum Microsoft 365 record for a domain that sends only from Microsoft 365 is:

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

Microsoft recommends -all (hard fail) for Microsoft 365 domains when you also use DKIM and DMARC. With ~all (soft fail), the DMARC policy is effectively ignored for SPF failures if the message has no DKIM signature. Do not use ?all in production. The GCC High and DoD clouds and Microsoft 365 operated by 21Vianet use different include values, which are listed in Microsoft's SPF page.

Microsoft also recommends a TTL of at least 3600 seconds on SPF TXT records to avoid DNS lookup timeouts.

Step 5: Publish and verify

  1. Lower your change risk by editing the record outside your busiest sending hours.
  2. Replace the existing record rather than adding a second one.
  3. Wait for the TTL of the old record to expire.
  4. Query the record again with the command from Step 1 and recount the lookups.
  5. Send a test message from each sender, including each third-party service, to a mailbox you can inspect, and check the Authentication-Results header for spf=pass.
  6. Watch DMARC reports and bounces for a week for senders you missed.

If you have not yet set up DKIM and DMARC, read SPF, DKIM and DMARC setup for Microsoft 365 and fixing a missing DKIM CNAME in Microsoft 365. SPF alone is not enough for protection against spoofing.

Troubleshooting

SymptomLikely causeFix
Bounce says the message exceeded the hop count or required too many lookupsMore than 10 lookupsWork through the fixes above
Permerror but fewer than 10 includesNested lookups or mx with many recordsRecount including nested records
One sender fails and others passFailing source is deep in the recordReorder or reduce, and recount
Permerror after adding a serviceSecond SPF TXT record publishedMerge into one record
Permerror with a short recordTypo or include without an SPF recordCheck the syntax table and query each include
Works at some receivers, not othersReceivers evaluate to different depthsReduce lookups, not just reorder
Subdomain mail fails SPFNo SPF record for that subdomainPublish a record for it

Checklist

  • One SPF TXT record per domain and per sending subdomain.
  • A documented list of every sender, with an owner for each.
  • Ten lookups or fewer, counted including nested includes.
  • Third-party senders on subdomains, not the main domain.
  • No flattening of include:spf.protection.outlook.com.
  • -all at the end, with DKIM and DMARC in place.
  • A quarterly review of any flattened ranges.

References

Questions people ask

What is the SPF 10 DNS lookup limit?

RFC 7208 caps the number of DNS-querying terms in an SPF evaluation at 10. The include, a, mx, ptr and exists mechanisms and the redirect modifier count, and ip4, ip6 and all do not. If the limit is exceeded, SPF returns a permanent error (permerror).

Does a long SPF record always fail?

No. Receivers evaluate sources from left to right and stop when the sending source matches. A record that could exceed 10 lookups may still work for some senders, but fail for sources listed later, which makes the problem intermittent and hard to spot.

Should I flatten include:spf.protection.outlook.com?

No. Microsoft advises against flattening the Microsoft 365 include, because its sending infrastructure uses dynamic IP addresses that change frequently. Flatten only vendors with stable, documented IP ranges, and review the result at least quarterly.

Can I have two SPF records to get more lookups?

No. Only one SPF record is allowed per domain or subdomain, and multiple SPF TXT records cause a permerror. To get more lookup budget, move services to subdomains, because each subdomain has its own SPF record and its own limit of 10.

SPFExchange OnlineDNSEmail authentication
  1. SPF, DKIM and DMARC for Microsoft 365: set up, test and reach p=reject

    Publish SPF, enable DKIM signing and roll DMARC out from p=none to p=reject for Microsoft 365 custom domains, with DNS examples, PowerShell commands and header checks.

    Microsoft 36512 min read
  2. Email migration cutover checklist: DNS TTLs, MX switch and day one

    A practical cutover runbook for moving a domain's mail to Exchange Online: lower TTLs early, switch MX and Autodiscover safely, and support users on day one.

    Microsoft 36510 min read
  3. Fix DKIM CnameMissing in Microsoft 365 and enable signing for your domain

    Why Microsoft 365 reports CnameMissing when you enable DKIM, how to publish the exact selector CNAME records, and how to confirm the domain signs mail.

    Microsoft 36510 min read
  4. Outlook Autodiscover problems with Microsoft 365: DNS checks and fixes

    Fix Outlook profiles that can't find an Exchange Online mailbox: check the Autodiscover CNAME, root domain responses, cached URLs, registry and Group Policy settings.

    Microsoft 36511 min read
  5. How to Add an Email Signature in Outlook (New Outlook, Classic, Web, Mobile) – 2026

    Step-by-step menu paths to add an email signature in the new Outlook, classic Outlook, Outlook on the web and the mobile apps, plus the options and limits for company-wide signatures in Microsoft 365.

    Microsoft 36515 min read
  6. Outlook Email Stuck in the Outbox: Fixes That Get Mail Sending Again

    Get queued messages out of the Outlook Outbox on Windows by checking Work Offline, removing large attachments, fixing Send immediately, and testing add-ins in safe mode.

    Microsoft 36510 min read