Too Many DNS Lookups: Fix SPF PermError for Google, Microsoft 365 & SendGrid

Published September 11, 2026 ยท 6 min read ยท spFlat!

"Too many DNS lookups" is still the most common reason SPF records fail at runtime. The 10-lookup limit in RFC 7208 is a hard ceiling: the 11th DNS-querying term stops evaluation with a PermError. That is not the same as an SPF fail, but many receivers (including Gmail) treat it badly enough that deliverability takes a hit.

The trap is counting the include: tokens you typed. Receivers count the whole chain. Google Workspace and Microsoft 365 have flattened their own records recently, so those two look cheap. Add SendGrid, Mailgun, or a CRM, and the math goes over 10 without anyone editing the obvious parts of your TXT record.


Why "too many DNS lookups" happens

Every include:, a, mx, ptr, exists, and redirect= counts as a DNS lookup. Nested includes count too. Direct ip4: and ip6: mechanisms do not. The initial lookup of your own SPF TXT record also does not count.

A record that looks like five includes is not five lookups:

v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:sendgrid.net include:mailgun.org include:_spf.salesforce.com ~all

Expanded today, that stack is typically 11 lookups, already over the limit:

  • _spf.google.com: Google now publishes IP ranges directly, so 1 lookup
  • spf.protection.outlook.com: Microsoft 365 is also a flat IP list, so 1 lookup
  • sendgrid.net still nests include:ab.sendgrid.net: 2 lookups
  • mailgun.org fans out through _spf.mailgun.org โ†’ _spf1/_spf2 plus the EU record: 5 lookups
  • _spf.salesforce.com uses exists: on top of the include: 2 lookups
Provider lookup counts drift. Google used to be four nested netblock includes. They flattened themselves. Last year's "Outlook is 3 lookups" is not this year's. Re-check the live chain; do not memorize a blog table forever.

Provider by provider

Google Workspace

Your Google include is one line:

v=spf1 include:_spf.google.com ~all

In 2026 that record is a list of ip4:/ip6: ranges, so it costs 1 lookup. It used to nest _netblocks.google.com, _netblocks2 and _netblocks3 (about 4 lookups). The leftover netblock names still exist; Google's top-level SPF no longer includes them. Cheap on its own, but still 1 of your 10.

Microsoft 365

Exchange Online uses include:spf.protection.outlook.com. That record is currently a flat IP list as well: 1 lookup. The trap is everything a Microsoft shop adds next: a marketing platform, Dynamics, a security gateway, or a second tenant include. Those are extra lookups on a budget that is already partly spent.

SendGrid

SendGrid still nests:

include:sendgrid.net

sendgrid.net publishes a long IP list and include:ab.sendgrid.net. Fully expanded, that is 2 lookups. Combined with Google, Outlook, Mailgun and a CRM, you are already over 10.

How to detect it (before mail is treated as unauthenticated)

Option 1: The spFlat! checker (free, no signup)

Go to spflat.cloud, enter your domain and hit Check. spFlat! looks up the full chain, including nested includes, and shows the lookup count a receiver would use, not the top-level token count.

Option 2: Manual dig

dig TXT yourdomain.com +short | grep -o 'include:[^ ]*' | while read inc; do
  dig TXT ${inc#include:} +short
done

This gives a rough count, but misses nested recursion unless you loop deeper, which is exactly where the extra lookups hide.

๐Ÿ”ด The kicker: some DNS validators stop at 10 lookups and do not show the rest of the tree. Your record can look "almost fine" in a dashboard and still return a PermError at the receiver.

How to fix it

The hard way: manual flattening

  1. Look up every include:, a: and mx: in your record
  2. Collect all resulting IP addresses and CIDR ranges
  3. Build a new record with only ip4: and ip6: mechanisms
  4. Publish it and hope the providers don't change their ranges
โš ๏ธ The problem: Google, Microsoft and SendGrid rotate IP ranges. A manually flattened record goes stale, and you only find out when mail starts bouncing. Dumping every CIDR onto your own domain also exceeds DNS size limits; see the 255-character / TXT size problem.

The smart way: spFlat!

spFlat! keeps the record a receiver evaluates under the 10-lookup limit and current:

  1. Check your domain to see the real lookup count instantly
  2. Add your sending services (Google, Microsoft 365, SendGrid, Mailgun, and whatever else you actually use)
  3. Publish one include, typically v=spf1 include:_yourdomain.spf.spflat.cloud ~all (one lookup). spFlat! monitors provider IP changes 24/7 and updates the flattened record behind that include.

Prevention

  • Add new services through spFlat! instead of editing the TXT record directly
  • Re-check after every provider change: one new include can silently push you over the limit
  • Monitor DMARC reports: a sudden drop in SPF alignment is often the first sign of a broken chain

๐Ÿ” Check your domain now

Ten seconds. Free. See exactly how many lookups your SPF record consumes, including all nested includes. Over 10? Flatten with spFlat! in a 14-day trial.

Check Your SPF
Or start your free 14-day trial โ†’

Frequently asked questions

How many SPF DNS lookups do Google Workspace and Microsoft 365 use?

In 2026 both are typically 1 lookup each when evaluated alone: _spf.google.com and spf.protection.outlook.com publish flat IP lists. They used to nest more includes, so older blog tables are outdated. Each still spends 1 of your 10 before you add marketing or CRM platforms.

Why does Google plus Microsoft 365 plus SendGrid exceed the SPF 10-lookup limit?

Receivers count the full nested chain, not the include tokens you typed. Google and Outlook may be 1 lookup each, but SendGrid still nests (about 2), and Mailgun or Salesforce can add several more. A common Google + Outlook + SendGrid + Mailgun + CRM stack is around 11 lookups and already ends in a PermError.

How do I fix too many DNS lookups for Google, Microsoft 365, and SendGrid?

Stop stacking every provider include on your domain. Flatten into ip4:/ip6: only if you will keep it updated, or publish one include to an automated flattening service that monitors provider IP changes. Re-check after every new sender; provider lookup counts drift over time.