गाइड · ईमेल

Fix SPF "Too Many DNS Lookups" (Permerror): Count, Trim and Flatten

Your SPF record can only trigger 10 DNS lookups. Learn what counts, how to count them, and how to fix a permerror by pruning, splitting and flattening.

लेखक: SiteDownCheck संपादकीय टीम · अपडेट: अक्टूबर 4, 2026 · 8 मिनट पढ़ने में

If a DMARC report or a header check says spf=permerror or "too many DNS lookups", your SPF record is being ignored by some receivers, and mail that relied on it may fail authentication. The cause is a hard limit in the SPF specification that stacked include: entries exceed very easily. This guide shows you how to count lookups exactly, decide what to cut, and choose between pruning, subdomain splitting and flattening.

The rule, precisely

RFC 7208 limits SPF evaluation to 10 DNS-querying mechanisms and modifiers per check. Going over does not produce a soft warning; the result is permerror, and the receiver treats SPF as having failed to evaluate. What happens next depends on the receiver and on your DMARC policy, but you should assume that mail may be rejected or marked as suspicious.

What counts

These terms each cost one lookup when evaluated:

  • include:
  • a (with or without a domain)
  • mx
  • ptr (also discouraged by the RFC; avoid it)
  • exists:
  • the redirect= modifier

What does not count

  • ip4: and ip6:, which are literal addresses and need no query
  • all
  • v=spf1 itself
  • the exp= modifier, which is only used after a failure to fetch an explanation string

The detail that surprises people: nesting

The limit applies to the whole evaluation tree, not to your record alone. If you write include:_spf.provider.example, that is one lookup, but the provider's record might itself contain four more include: terms and several a or mx terms. All of those count against your total of 10.

Two further wrinkles:

  • An mx mechanism counts as one lookup toward the ten, but it also triggers address queries for each MX host. The specification separately caps those at 10 MX names per mechanism, and exceeding that is a permerror too. So mx is not free if you have many mail hosts. Check the result with a tool rather than by eye.
  • A mechanism that resolves to nothing is a "void lookup".

The void lookup limit

RFC 7208 also says that evaluating more than two lookups that return no data (an NXDOMAIN or an empty answer) should cause a permerror. So a record containing include: entries for services you cancelled, whose records no longer exist, can break SPF even if you are far below ten. Stale entries are doubly harmful: they spend your budget and can trip the void limit.

How to count lookups

Manual count

Take your record and walk it recursively.

dig TXT example.com +short | grep spf1
# "v=spf1 include:_spf.workspace.example include:spf.transactional.example include:spf.crm.example mx a -all"

Then expand each include:

dig TXT _spf.workspace.example +short
dig TXT spf.transactional.example +short
dig TXT spf.crm.example +short

Keep a tally: each include, a, mx, exists, ptr and redirect you meet, at any depth, adds one.

A worked example, with documentation names:

example.com            v=spf1 include:_spf.workspace.example include:spf.transactional.example mx a -all
  _spf.workspace.example      v=spf1 include:_netblocks1.workspace.example include:_netblocks2.workspace.example ~all
    _netblocks1.workspace.example   v=spf1 ip4:198.51.100.0/24 ip4:203.0.113.0/24 ~all
    _netblocks2.workspace.example   v=spf1 ip6:2001:db8::/32 ~all
  spf.transactional.example   v=spf1 ip4:192.0.2.0/25 include:relay.transactional.example ~all
    relay.transactional.example     v=spf1 ip4:192.0.2.128/25 -all

The tally:

TermCount
include:_spf.workspace.example1
include:_netblocks1.workspace.example (nested)2
include:_netblocks2.workspace.example (nested)3
include:spf.transactional.example4
include:relay.transactional.example (nested)5
mx6
a7

Seven out of ten, so one more provider with a similar structure would push it over. The ip4 and ip6 terms cost nothing.

Using a tool

The Email DNS Checker evaluates your SPF record and reports the lookup count, flagging void lookups and multiple SPF records. Cross-check by querying the individual includes with the DNS चेकर. Receivers may count slightly differently around edge cases, so leave headroom rather than sitting at exactly ten.

Fix it, in order of preference

1. Remove what you no longer use

This is the cheapest fix and often enough. Audit every include::

  • Which services still send mail as your domain?
  • Which were trials, former agencies, or retired tools?

Use DMARC aggregate reports (see the SPF, DKIM and DMARC guide) to see which senders are really active. Remove entries for services with no traffic, and confirm with the people who run them before deleting. This also removes void-lookup risk.

2. Replace a and mx with explicit addresses where stable

If your own mail server's address never changes, ip4:203.0.113.25 costs zero lookups, while mx costs at least one and more as your MX hosts multiply. Be careful: if the address changes and you forget to update SPF, mail will fail. Document the dependency.

Also drop a and mx if they are not needed. Many records include both out of habit. You only need mx if your inbound servers also send outbound mail, and a only if your web server sends mail.

3. Move senders to subdomains

Each domain and subdomain gets its own SPF record with its own budget of ten. Marketing platforms and transactional services can send as news.example.com or mail.example.com, with their own SPF record and DKIM, instead of piling into the root.

example.com.        IN TXT "v=spf1 include:_spf.workspace.example -all"
news.example.com.   IN TXT "v=spf1 include:spf.newsletter.example -all"
app.example.com.    IN TXT "v=spf1 include:spf.transactional.example -all"

Remember that DMARC alignment still has to work: using the subdomain in the From address (news@news.example.com) means relaxed alignment will accept it under the organisational domain. This is the cleanest long-term fix because it also isolates reputation between mail streams.

4. Use a redirect or a single provider where possible

If a whole domain sends only through one provider, v=spf1 redirect=_spf.provider.example is one lookup and delegates the entire policy. Note that redirect= is ignored if the record also contains an all mechanism, so use one or the other.

5. Flatten, with open eyes

Flattening replaces include: terms with the ip4:/ip6: ranges they currently resolve to, taking the lookups to zero. It works, but carries real costs:

  • Providers change their IP ranges. A flattened record is a photograph; the next time the provider adds a server, your copy is out of date and legitimate mail starts failing.
  • Record size: a long list of addresses can exceed the 255-character limit of a single TXT string (you must split it into multiple quoted strings inside one record) and approach the 512-byte UDP response size that older resolvers expect. Very large records push responses into TCP or truncate, and some DNS hosts impose their own limits.
  • Manual maintenance does not scale. If you flatten, automate it: a scheduled job or a managed flattening service that re-resolves includes and republishes when ranges change, with alerting if that job fails.

Flatten only the senders whose ranges are stable, and keep include: for the ones that change often. A hybrid is perfectly acceptable.

Step-by-step procedure

  1. Capture the current record and save the output.
  2. Run the lookup counter in the Email DNS Checker to see your total and any void lookups.
  3. List every sender and check each against recent DMARC reports. Mark which are active.
  4. Delete dead includes and re-test.
  5. Replace a/mx with ip4/ip6 where addresses are stable.
  6. If still near the limit, move bulk or transactional senders to subdomains, giving each a record and DKIM.
  7. Consider flattening only what remains if it is stable, with automation.
  8. Publish a single record. Never leave two SPF TXT records. Edit the existing one.
  9. Re-test: send mail through each remaining sender to the ईमेल डिलीवरेबिलिटी टेस्ट and confirm spf=pass.
  10. Watch DMARC reports for a week or two for failures you missed.

You can draft a clean record with the SPF & DMARC Generator, but confirm the lookup count yourself afterwards because generators cannot know what third-party includes will expand to in future.

Mistakes that keep the problem alive

  • Adding an include: every time a tool asks, without removing old ones.
  • Leaving ptr in the record from legacy templates. It is slow, unreliable and counts toward the limit.
  • Counting only top-level terms and ignoring nested includes.
  • Publishing a second SPF record "just for the new tool". Multiple SPF records are a permerror in themselves.
  • Treating ~all versus -all as a lookup issue. It is not related; the lookup limit is hit before the ending matters.
  • Forgetting that the redirect= target's lookups count too.

अगले कदम

सामान्य प्रश्न

What happens when SPF exceeds 10 lookups?

The evaluation returns permerror. Receivers differ in how they treat it, but SPF cannot be relied upon to pass, and DMARC will then depend entirely on DKIM alignment. Some mail may be rejected or filtered.

Do ip4 and ip6 mechanisms count toward the limit?

No. Neither do all nor the v=spf1 marker. Only terms that require DNS queries, namely include, a, mx, ptr, exists and redirect, are counted.

Do nested includes count?

Yes. The limit applies to every DNS-querying term encountered while evaluating the full chain, including terms inside the records your includes point to. A single include: can cost several lookups.

Is SPF flattening a good idea?

It can be, for small stable sets of addresses, but a static flattened record goes stale when providers change ranges. If you flatten, automate regeneration and alert on failure, or prefer moving senders to subdomains.

What is the void lookup limit?

RFC 7208 says that more than two lookups returning no data (NXDOMAIN or an empty answer) should produce a permerror. Stale include: entries for services that no longer publish SPF are the usual cause.

Get notified when this guide updates

Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.

यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.