How to fix SPF PermError: too many DNS lookups
SPF allows at most 10 DNS-querying terms (include, a, mx, ptr, exists and redirect) per check. Over that, receivers return PermError and your SPF stops counting. To fix it, remove unused senders, drop a and mx where they don't send, move bulk tools to subdomains, and rely on aligned DKIM for DMARC.
On this page 10 sections
What does "too many DNS lookups" mean in SPF?
SPF (RFC 7208) is a TXT record listing who may send mail for your domain. To check it, a receiving server may need to make more DNS queries: one for each include, each a, each mx, and so on, including inside the records you include.
To stop SPF being used to flood DNS servers, section 4.6.4 of the RFC sets hard limits:
| Limit | What counts | What happens if exceeded |
|---|---|---|
| 10 DNS-querying terms per evaluation | include, a, mx, ptr, exists, redirect |
PermError |
| 2 void lookups (recommended) | Lookups that return no records or "domain doesn't exist" | PermError |
10 address lookups per mx mechanism |
The A/AAAA lookups for each MX host | That mx returns PermError |
10 address lookups per ptr |
Names returned by the reverse lookup | Extra names are ignored |
| Free | ip4, ip6, all |
— |
The 10 is counted across the whole tree. If you include a vendor whose record includes three more records, that's four lookups, not one.
When a receiver gets PermError, your SPF result is unusable. For DMARC (RFC 9989), that means SPF can't provide the aligned pass. If DKIM doesn't pass and align either, DMARC fails.
Why do Microsoft 365 and Google Workspace domains hit the limit?
Neither platform's base record is the problem on its own. When we looked up both records on 9 October 2026, spf.protection.outlook.com and _spf.google.com each contained only ip4 and ip6 ranges, so each include cost one lookup.
The trouble is everything added over the years:
- A newsletter platform, a CRM, a helpdesk, an invoicing tool, a website contact form.
aandmxmechanisms added "just in case", which cost a lookup each.- Includes for services you stopped using, which often become void lookups.
- A filtering service's include added to SPF even though it only handles inbound mail.
Each vendor tells you to add their include. Nobody adds up the total. Our SPF records by email provider table lists what each common include costs, measured, and which services don't need one at all.
How do you count SPF lookups by hand?
A checker does this for you, but knowing the method helps you judge each vendor's request before you add it.
- Start at your domain's SPF record. Every
include,a,mx,ptr,existsandredirectcosts one. - For each
include, fetch that domain's SPF record and repeat. Its mechanisms count toward your total too. - Ignore
ip4,ip6andall. They cost nothing. - Note any lookup that returns no record or a non-existent domain. That's a void lookup; more than two is PermError.
- Stop at 11. If you reach it, the record is broken for every receiver that follows the RFC.
For example, v=spf1 mx include:spf.protection.outlook.com include:vendor.example -all, where vendor.example itself contains two more includes, costs 1 (mx) + 1 (Microsoft) + 1 (vendor) + 2 (vendor's includes) = 5.
Our SPF records by email provider pages list the measured cost of each common include, from Microsoft 365 and Google Workspace to sending services such as SendGrid and Amazon SES.
Does switching to ~all or +all fix it?
People sometimes try to make the error go away by loosening the ending. It doesn't work. The lookup limit is reached before the all mechanism is ever evaluated, so changing -all to ~all changes nothing. Changing it to +all makes SPF meaningless, because it authorizes every server on the internet to send as you. Removing SPF entirely is worse still: Google and Yahoo require SPF from bulk senders, and receivers lose a signal that helps your real mail.
How do you fix too many SPF lookups?
-
Measure where you are. Run your domain through the SPF Checker. Note the total lookup count, the void lookup count, and which branch of the include tree uses the most.
-
Check for duplicate records. If there are two TXT records starting with
v=spf1, that alone is PermError (RFC 7208, section 4.5). Merge them into one before doing anything else. -
List who really sends as your domain. Check DMARC aggregate reports if you have them. Otherwise ask each team what tools send email "from" your domain. Write down each service and whether it sends from the main domain or could use a subdomain.
-
Remove what you don't use. Delete includes for retired services. This often fixes void lookups at the same time.
-
Drop
a,mxandptrunless they send.mxauthorizes your inbound servers to send. If your MX points to Microsoft 365, Google, or a filtering service,mxis usually redundant because the platform include already covers outbound.ptris slow and RFC 7208 says not to use it. -
Don't add inbound-only services. A filtering service that only receives mail for you doesn't need to be in your SPF. Only add an include for a service that sends mail with your domain in the envelope sender, such as an outbound relay.
-
Move bulk and marketing senders to a subdomain. For example, send newsletters from
news.example.com. That subdomain gets its own SPF record with its own budget of 10:example.com. TXT "v=spf1 include:spf.protection.outlook.com -all" news.example.com. TXT "v=spf1 include:mailer.example.net -all"With relaxed alignment (the DMARC default),
news.example.comstill aligns withexample.com. -
Set up DKIM everywhere. Configure custom DKIM signing with your domain in each sending tool. DMARC passes if either SPF or DKIM passes with alignment, so DKIM gives you a second route and survives forwarding better.
-
Consider flattening only as a last resort. Replacing an include with the vendor's current
ip4/ip6ranges saves lookups, but breaks the moment the vendor changes addresses. If you flatten, automate updates. -
Re-check and monitor. Run the checker again. Vendors change their own records, so a record that passes today can break next month without you touching it.
Example: before and after
A Microsoft 365 domain that had grown over time:
Before:
v=spf1 a mx include:spf.protection.outlook.com include:_spf.google.com
include:mailer.example.net include:crm.example.org include:helpdesk.example.io
include:old-newsletter.example.com include:invoices.example.co ~all
The domain moved from Google Workspace to Microsoft 365 two years ago, and the old newsletter service is gone. After removing those, dropping a mx, and moving the newsletter tool to a subdomain:
After:
example.com. TXT "v=spf1 include:spf.protection.outlook.com include:crm.example.org
include:helpdesk.example.io include:invoices.example.co -all"
news.example.com. TXT "v=spf1 include:mailer.example.net -all"
The exact count depends on what each vendor's include contains today. Measure, don't guess.
What are the common mistakes?
| Mistake | Why it hurts | Fix |
|---|---|---|
| Two SPF records | PermError immediately | Merge into one |
redirect plus all |
redirect is ignored when all is present (section 6.1) |
Use one or the other |
redirect to a domain with no SPF |
PermError, not "none" | Point it at a domain that publishes SPF |
Using +all to "fix" failures |
Authorizes the whole internet | Use ~all or -all |
| Adding the inbound filter's include | Wastes a lookup on a host that doesn't send for you | Only list outbound senders |
How do you check the fix worked?
DNS changes aren't instant. Resolvers keep the old record until its TTL expires, so wait at least that long before testing.
- Run the SPF Checker again and confirm the lookup count is 10 or under, with no more than two void lookups.
- Send a test message from each service you kept, for example your mailbox, your CRM and your helpdesk, to a mailbox at a different provider.
- Open each message's headers in the Email Header Analyzer and confirm
spf=passor, where SPF doesn't align,dkim=passwith alignment. - If you publish DMARC with a
ruaaddress, watch the next week of aggregate reports for any source that stopped passing.
Leave some headroom. A record sitting at exactly 10 breaks the moment one vendor adds an include to its own record.
How iBlockSpam helps
Our free SPF Checker counts lookups across the whole include tree and shows where they're spent, and the SPF Record Generator estimates the lookup count of a rebuilt record before you publish it. If you use iBlockSpam for inbound filtering, you don't add anything to SPF for inbound mail. If you use our outbound relay (with DKIM signing, 500 messages per month included), the setup wizard shows what, if anything, to change in SPF and compares your DNS before and after. Domain monitoring alerts you when your SPF record changes: weekly on Protect, daily on Protect Plus. We don't flatten records for you.
Next steps
- Count your lookups with the free SPF Checker.
- Remove includes for services you no longer use, then rebuild the record with the SPF Record Generator.
- Re-check after every new sending service you add.
A record that is under the limit today can go over it when a vendor changes its include. The free Free Domain Watch re-checks your SPF record every week and emails you if it changes.
Browse our other SPF, DKIM and DMARC guides.
Frequently asked questions
Do ip4 and ip6 count toward the 10 lookup limit?
No. Only include, a, mx, ptr, exists and the redirect modifier count. ip4, ip6 and all don't need DNS queries, so you can list as many addresses as you like, within the size limits of a TXT record.
Is SPF flattening a good idea?
It works, but it's fragile. Flattening copies a vendor's IP addresses into your record. When the vendor changes its addresses, your record is silently wrong. Only flatten with a tool that updates automatically, and prefer subdomains first.
How many lookups does Microsoft 365 or Google Workspace use?
When we checked in October 2026, include:spf.protection.outlook.com and include:_spf.google.com each cost one lookup, because those records contain only IP ranges. Vendors can change that at any time, so check with our SPF Checker.
Will a PermError make my mail bounce?
Usually not directly. SPF simply stops helping you. If DKIM passes and aligns, DMARC can still pass. If it doesn't, receivers may treat the message as unauthenticated and junk or reject it.
Sources
See how your domain measures up
Run a free Email Health Check: MX, SPF, DKIM, DMARC and transport security in one scan, with the raw records shown. No sign-up.
Keep reading
SPF record syntax and examples
SPF record syntax explained: mechanisms, qualifiers and modifiers, with copy-ready examples for Microsoft 365, Google Workspace, subdomains and parked domains.
9 min read SPF, DKIM & DMARCWhat is SPF, and how does an SPF record work?
What an SPF record is, how receivers check it against the envelope sender, the 10-lookup limit, what SPF can't do, and how to create one for your domain.
9 min read SPF, DKIM & DMARCMultiple SPF records found: why it causes PermError and how to merge them
Why a domain can have only one v=spf1 record, how two SPF records cause PermError and break DMARC, and how to merge them into one record safely, step by step.
8 min read