SPF

SPF permanent error: too many dns lookups

SPF "too many DNS lookups" is an RFC 7208 permerror: your record exceeds 10 DNS-querying terms. Learn what counts toward the limit and how to get back under 10.

Updated Jul 1, 2026

The short answer

This SPF "permerror" means your domain's SPF record forces more than 10 DNS-querying terms during evaluation, the hard limit set by RFC 7208 §4.6.4. Receivers stop and return permerror, which DMARC treats as an SPF fail. Fix it by counting your include/a/mx/exists/redirect terms and getting back under 10: remove unused vendors, replace lookups with ip4/ip6, and drop mx.

SPF authentication evaluates your sending domain's TXT record top to bottom. To protect resolvers from amplification and DoS, RFC 7208 §4.6.4 caps the number of terms that trigger DNS queries at 10 per SPF check. Exceed that and the receiver stops evaluating and returns a permanent error (permerror) — it does not "fail open" or keep counting.

What causes "SPF permerror: too many DNS lookups"?

Only the terms that cause a DNS query count toward the limit of 10:

  • include — each counts as 1, no matter how deeply nested
  • a, mx, exists — each counts as 1
  • redirect — counts as 1
  • ptr — counts as 1 (and is discouraged; see below)

Terms that need no DNS query do not count: all, ip4, ip6, and the exp modifier.

The trap is nesting. An include: pulls in another domain's SPF record, whose own include/a/mx terms all add to your total. A single include:sendgrid.net or a marketing-automation platform's include can expand to several lookups once you count their nested includes. Stack three or four vendors (a CRM, a help desk, a marketing platform, an ESP) and you blow past 10 — even though your own record only lists a handful of terms. (As of December 2025, Google flattened _spf.google.com from four lookups down to one, so it no longer eats disproportionately into the budget — but its IP ranges are still large and rotating, so keep the include rather than hardcoding IPs.)

Two clarifications people get wrong:

  • A term's count is not its query count. Per RFC 7208, mx counts as one term even though the receiver must resolve the MX hosts and then their A/AAAA records (1+N queries). The term budget is what's capped at 10. (There are separate sub-limits: mx and ptr may not trigger more than 10 address-record lookups each.)
  • There is a second limit. RFC 7208 also recommends a max of 2 "void lookups" (queries returning NXDOMAIN or an empty answer). A stale include: pointing at a retired vendor domain can trip this and produce permerror independently of the count-of-10.

A permerror is not a pass, so it cannot satisfy DMARC's SPF-alignment check. RFC 7489 §6.6.2 technically leaves handling of permanent authentication errors to receiver discretion, but in practice virtually all major mail receivers treat permerror the same as a fail for DMARC purposes — so exceeding the 10-lookup limit still hurts deliverability and alignment unless DKIM alignment passes instead.

How do I fix SPF too many DNS lookups?

The goal is simple: get the DNS-querying terms (counting nested ones) back to 10 or fewer. Use an SPF checker that reports the exact lookup count, then:

  1. Remove vendors you no longer send through. This is the most common and safest win — old include: entries for tools you've stopped using are pure dead weight. Removing one nested include can reclaim several lookups.
  2. Replace lookups with ip4/ip6 where the IPs are stable and small. A vendor with one or two fixed egress IPs can be expressed as ip4:198.51.100.10 instead of an include: that expands. These cost zero lookups. Only do this where the provider publishes stable IPs — for large rotating ranges (e.g. Google, even post-flattening) keep the include.
  3. Drop mx if you don't send from your MX hosts. Many domains carry mx out of habit while actually sending only through third parties. If your inbound mail servers aren't also outbound senders, remove it and reclaim a term (plus its 1+N queries).
  4. Eliminate ptr. RFC 7208 §5.5 explicitly says the ptr mechanism "SHOULD NOT be published" — it is slow, unreliable, and a lookup you almost never need.
  5. Audit nested includes. Expand each include: to see which contributes the most. Consolidate or remove redundant vendors that resolve to overlapping infrastructure.

A correct, lean record looks like:

v=spf1 include:_spf.google.com include:sendgrid.net ip4:198.51.100.10 ~all

A note on "SPF flattening"

Flattening tools replace include: terms with the raw ip4/ip6 ranges they currently resolve to, eliminating lookups. It works, but use it with caution: vendors change their sending IPs without notice, so a flattened record goes stale silently and starts failing legitimate mail unless you re-flatten on a schedule (typically via an automated, hosted service). Prefer the manual cleanup above first; reach for flattening only when you genuinely need many vendors and can commit to keeping the flattened list maintained.

With Courier

If you send through Courier, your transactional traffic is delivered via Courier's configured email provider rather than by stacking another include: onto your own record — so consolidating senders behind Courier can reduce the number of vendor includes your domain has to authorize directly. Authenticate the provider Courier routes through per its setup docs, then re-count your terms.

FAQ

Common questions

It counts terms that cause a DNS lookup, not the raw number of queries. RFC 7208 §4.6.4 limits include, a, mx, ptr, exists, and redirect to 10 total — each counts as one even when nested. Note that mx is one term but may itself trigger multiple address-record queries (1+N).

One API, every provider

Stop debugging raw provider errors

Courier connects to your email, SMS, and push providers, handles retries and failover, and surfaces delivery errors in plain language.

Reply-code definitions per RFC 7208 §4.6.4. Last reviewed Jul 1, 2026. Courier is not affiliated with third-party providers; error behavior may vary by implementation.