If you are managing email for a small business or a hosting client, you have likely encountered the dreaded "SPF PermError: too many DNS lookups" rejection. This error does not mean your server is compromised or that your domain is blacklisted. It means your SPF (Sender Policy Framework) record has become a bloated mess of third-party include: statements that exceeds the strict, globally enforced 10-lookup limit.
Every time you add a new service—Microsoft 365 for daily email, Mailchimp for newsletters, Mailgun for marketing, or a CRM like Zendesk—they tell you to "just add this include to your SPF record." Following these instructions blindly guarantees you will break the limit. When a receiving server (like Gmail or Yahoo) queries your SPF record, it must resolve every nested DNS request. If it hits 11 lookups, it drops the connection, and your emails fail DMARC alignment.
This runbook is not about theoretical email infrastructure; it is a practical guide to dissecting a broken SPF record, identifying the hidden lookups, and flattening it so your transactional and marketing emails actually reach the inbox.
Understanding the 10-Lookup Limit
The SPF specification (RFC 7208) exists to prevent email spoofing. It dictates exactly which IP addresses are authorized to send mail on behalf of your domain. To prevent malicious actors from creating infinite DNS loops that could take down mail servers (a form of Denial of Service attack), the RFC mandates a hard limit: a maximum of 10 DNS lookups to resolve the entire SPF policy.
The mechanisms that consume a lookup are include, a, mx, ptr, and exists. The mechanisms ip4, ip6, and all do not require DNS lookups and do not count toward the limit.
The trap lies in nested lookups. If you include Microsoft 365 (include:spf.protection.outlook.com), you are not consuming just one lookup. Microsoft’s record includes other records, which include other records. Microsoft alone often consumes two or three of your ten available lookups. Add a marketing tool, and you are instantly over the edge.
Diagnosing a Broken SPF Record
Let's look at a typical, failing SPF record for a small business hosted on a virtual server. The administrator manages their own web server, uses Microsoft 365 for corporate mail, sends newsletters via Mailchimp, and processes transactional receipts via SendGrid.
v=spf1 mx a include:spf.protection.outlook.com include:servers.mcsv.net include:sendgrid.net -all
To the naked eye, this looks like five lookups (mx, a, and three includes). However, when you run this through an SPF checker or parse it manually with dig, the reality is much worse.
- mx: 1 lookup.
- a: 1 lookup.
- include:spf.protection.outlook.com: This resolves to another record containing
include:spfa.protection.outlook.comandinclude:spfb.protection.outlook.com. That is 1 lookup for the main record, plus 2 for the nested ones. Total: 3 lookups. - include:servers.mcsv.net (Mailchimp): This often resolves to multiple nested includes or A records depending on their current routing. Conservatively, it consumes 3 to 4 lookups.
- include:sendgrid.net: Resolves to multiple sub-records. Usually consumes 2 to 3 lookups.
This record easily totals 10 to 12 lookups. Any email sent from this domain is at high risk of being rejected with a PermError. If you manage client domains, failing to monitor this will result in immediate support tickets when invoices stop delivering.
Step 1: Eliminate Redundant Mechanisms
The first step in cleaning an SPF record is removing mechanisms that provide no value. Sysadmins often leave a and mx in the record by default.
If your web server (the A record of your domain) does not send email directly, remove the a mechanism. If you use Microsoft 365, your MX records point to Microsoft, not your own server. Microsoft’s IPs are already covered by include:spf.protection.outlook.com. Therefore, the mx mechanism is entirely redundant and wastes a precious lookup.
By simply deleting a and mx, we instantly reclaim two DNS lookups.
v=spf1 include:spf.protection.outlook.com include:servers.mcsv.net include:sendgrid.net -all
Step 2: Replace Includes with IPv4/IPv6 Addresses
Because ip4 and ip6 mechanisms do not require DNS lookups, you can replace a DNS-heavy include with the direct IP ranges of the provider. This is known as SPF flattening.
For example, if you have a dedicated IP address on your VPS that sends system alerts, do not use a. Hardcode the IP.
If a service provider has a static, publicly documented list of IP subnets (like many transactional mailers do), you can query their include record and extract the IPs. Let's assume you query a hypothetical small mailer and find it uses two IPv4 blocks.
dig TXT _spf.smallmailer.com +short
"v=spf1 ip4:192.168.1.0/24 ip4:10.0.0.0/8 -all"
You can remove include:_spf.smallmailer.com (which costs 1 lookup) and replace it with ip4:192.168.1.0/24 ip4:10.0.0.0/8 (which costs 0 lookups).
Warning: Do not manually flatten massive, dynamic providers like Microsoft 365 or Google Workspace. They rotate their IP blocks constantly. If you hardcode their IPs and they change them, your emails will fail immediately. Only flatten static, dedicated IPs or use automated dynamic flattening services for the big players.
Step 3: Segregate Mail Streams with Subdomains
The most robust, sysadmin-approved method to fix SPF bloat is to stop sending all mail from your root domain. You should segment your traffic. The root domain should be reserved exclusively for human-to-human corporate communication (e.g., Microsoft 365 or Google Workspace).
Marketing emails, transactional receipts, and automated CRM replies should be moved to dedicated subdomains. SPF limits apply per domain/subdomain. A subdomain has its own, separate 10-lookup limit.
Instead of putting everything on @example.com, configure it like this:
Corporate Mail (Microsoft 365): @example.com
v=spf1 include:spf.protection.outlook.com -all
Marketing Mail (Mailchimp): @news.example.com
v=spf1 include:servers.mcsv.net -all
Transactional Mail (SendGrid): @receipts.example.com
v=spf1 include:sendgrid.net -all
By doing this, the root domain now uses a maximum of 3 lookups (just Microsoft). The subdomains have plenty of headroom. Furthermore, if your marketing team ruins the reputation of news.example.com by triggering spam filters, it will not affect the deliverability of your CEO's emails coming from the root domain.
Validating the Fix
After refactoring the records, you must validate the setup using a tool like dig or an online SPF verifier. Never guess with DNS authentication. An invalid syntax will result in immediate mail drops.
If you run a check on the optimized root domain, the output should confirm a clean path with minimal hops:
Result: Pass
Total Lookups: 3/10
Syntax: Valid
Mechanisms: 1 (include)
Managing email infrastructure requires a strict adherence to RFCs and an understanding of how DNS scales. If you are reading hosting terms of service to find out why your host isn't fixing your email delivery, the harsh truth is that DNS configuration is almost always the client's responsibility. Clean up your records, segment your traffic, and your deliverability issues will disappear.
Source & Attribution
This article is based on original data belonging to serverspan.com blog. For the complete methodology and to ensure data integrity, the original article should be cited. The canonical source is available at: SPF "Too Many DNS Lookups" Runbook: Cleaning Up Email Authentication for Small Hosts.