← Back to Blog

SPF PermError "too many DNS lookups": how to get under the 10-lookup limit without breaking mail

SPF PermError "too many DNS lookups": how to get under the 10-lookup limit without breaking mail

Why the limit exists

SPF is not a list of IP addresses you publish once. It is a small program a receiving mail server has to run: fetch your TXT record, then follow every include, a, mx, ptr, and exists mechanism, plus any redirect modifier, each of which triggers its own DNS lookup. RFC 7208 section 4.6.4 caps that at 10: "SPF implementations MUST limit the total number of those terms to 10 during SPF evaluation, to avoid unreasonable load on the DNS." Cross it and "the implementation MUST return permerror."

PermError is not a soft failure. It does not mean "treat this as neutral" the way a missing record does. Most large receivers, Gmail included, treat an SPF PermError as equivalent to no valid SPF at all, and Gmail's bulk sender rules require SPF or DKIM to pass, so a domain that blows the lookup budget can start bouncing with unauthenticated errors even though the record looks fine at a glance.

Two related limits sit inside that same rule. Each MX mechanism you use must not require querying more than 10 A or AAAA records to resolve, and the same 10-record cap applies to PTR lookups. RFC 7208 also recommends implementations cap "void lookups," DNS queries that return nothing, at two, and return permerror past that. In practice this means a bloated record can fail even before you count all 10 real lookups, if enough of those lookups come back empty.

Counting your lookups honestly

The mistake most SPF records make is counting the top-level include statements and stopping there. The limit is not "10 includes," it is 10 total DNS lookups across the whole evaluation, and an include can itself contain more includes that each cost a lookup.

Take a record that looks harmless:

v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:servers.mcsv.net include:spf.zoho.com redirect=_hspf.hubspot.com a mx include:sendgrid.net ~all

Read left to right against the RFC's list of what counts (include, a, mx, ptr, exists, redirect): include:_spf.google.com is 1, include:spf.protection.outlook.com is 1, include:servers.mcsv.net is 1, include:spf.zoho.com is 1, the a mechanism is 1, the mx mechanism is 1, and include:sendgrid.net is 1. That is 7 so far, before touching the HubSpot redirect. HubSpot's own SPF chain is not flat. Following it as published today means redirect=_hspf.hubspot.com (1 lookup) resolves to a record that itself includes _hspf1.hubspot.com (1 more), which includes _hspf2.hubspot.com (1 more), which includes a further sub-record. That redirect chain alone adds 4 or more lookups on top of the 7, pushing the total to 11 or higher, past the limit, on a record that looked like six or seven modest entries.

The usual offenders

Not every provider is equally expensive. As currently published, Google Workspace's include:_spf.google.com resolves directly to a flat list of IP ranges, no nested includes, so it costs exactly 1 lookup. Microsoft 365's include:spf.protection.outlook.com is the same shape: flat, 1 lookup. Mailchimp's include:servers.mcsv.net is also flat, 1 lookup. Zoho's include:spf.zoho.com resolves to a single flat list as well, 1 lookup, though Zoho's own documentation sometimes shows a combined record with additional includes like zcsend.net for their marketing product, each adding another lookup. HubSpot is the outlier: its SPF is a multi-level redirect and include chain, and following it end to end costs 4 or more lookups by itself, more than any other mainstream provider in a typical stack.

This changes over time. Providers restructure their SPF infrastructure without warning, and a provider that is flat today can add nested includes next quarter. Treat any lookup count, including the ones above, as something to re-verify with a live tool rather than something to hardcode into a spreadsheet.

Fix 1: remove dead includes

The fastest win is almost always deleting mechanisms nobody uses anymore. SPF records accumulate the way old CC lists do: a marketing tool you canceled two years ago, a fax-to-email gateway nobody remembers, a legacy on-prem relay that got decommissioned when you moved to Workspace or M365. Pull the current record, match every include against a live sender, and delete anything that is not sending mail today. This alone resolves a large share of "too many lookups" cases without touching anything else.

Fix 2: push the cost onto a subdomain

Every subdomain gets its own SPF evaluation and its own 10-lookup budget. If your root domain sends transactional mail through Workspace and marketing mail through HubSpot and Mailchimp, moving the marketing sends to a dedicated subdomain, for example mail.example.com or news.example.com, splits one crowded 10-lookup budget into two separate ones. This is also the fix dmarcian, the company that built and later retired its own SPF flattening tool, now recommends over flattening: segmenting senders by subdomain gives you "better controls, less attack surface, operational efficiency, and reputational resilience" instead of one bloated shared record.

Fix 3: flattening, and why it carries its own risk

Flattening replaces an include with the literal ip4/ip6 ranges it resolves to today, cutting the lookup count to near zero. It works, until the provider changes its sending IPs, which every major ESP does periodically without a public changelog. A flattened record goes stale the moment that happens, and mail from the provider's new IPs starts failing SPF silently, often before anyone notices the bounce pattern. dmarcian ran flattening as a public experiment for years and shut it down in March 2023, concluding that the practice trades one operational problem for a security one: an over-authorized, rarely-audited record is "unnecessary entries in SPF records" that widen your attack surface rather than shrink it. If you flatten, treat it as a stopgap with a recheck on your calendar, not a permanent fix.

Fix 4: lean on DKIM alignment instead of forcing SPF to cover everything

DMARC only needs one of SPF or DKIM to pass and align, not both. If a sender you cannot remove from SPF without breaking mail is properly DKIM-signed with an aligned domain, DMARC still passes for that sender even if SPF alone would exceed the lookup limit or fail outright. This does not fix the PermError risk, an SPF PermError is still treated as SPF failing outright by most receivers regardless of what DMARC ultimately decides, so it is a mitigation for alignment, not a substitute for getting the lookup count under 10. Prioritize DKIM setup for every sender you keep, and use it as the safety net while you work the SPF count down, not as a reason to ignore the count.

Verify before you consider it done

Publish the change, then re-check the live record rather than trusting your own count. A record that looked fine on paper can still exceed the limit once you follow a redirect chain like HubSpot's all the way down, and a typo in one include can silently break the whole record instead of just that one entry. Run a real test send through the Guanacos Tech email troubleshooter and confirm SPF returns pass, not permerror or none, on an actual message.

How Guanacos Tech helps

We see this most often in companies that have switched email or marketing platforms two or three times over the years and never cleaned up the trail. We audit the full lookup chain, including redirects and nested includes most SPF checkers stop counting after the first level, cut it under 10 in the right order, and set up DKIM alignment as backup coverage for anything that has to stay. If your SPF record keeps bouncing back as a PermError, book a call and we will trace it with you.

Sources

Frequently asked questions

What happens if my SPF record exceeds 10 DNS lookups?

RFC 7208 requires implementations to return permerror once the total of include, a, mx, ptr, exists, and redirect terms exceeds 10. Most receivers, including Gmail, treat SPF permerror the same as no valid SPF, which can trigger unauthenticated-mail rejections even though a record is published.

Does flattening my SPF record fix the lookup limit permanently?

It fixes the count immediately but creates a maintenance risk: flattened IP ranges go stale whenever the underlying provider changes its sending infrastructure, which happens periodically without notice. dmarcian, which built and later retired its own flattening tool, now recommends subdomain segmentation instead.

Do I still need to fix SPF if DKIM is already passing?

Yes, if you want SPF itself to return pass rather than permerror. DMARC only needs one of SPF or DKIM to pass and align, so DKIM can cover alignment for a sender you cannot remove, but an SPF permerror is still treated as an outright SPF failure by most receiving systems.