SPF Too Many DNS Lookups: Shrink It Safely and Pass Checks

Was this helpful?

Your outbound mail is “configured,” your DNS looks “fine,” and yet deliverability tanks overnight because SPF returns permerror: too many DNS lookups. Marketing swears nothing changed. Your helpdesk swears everything changed. You get to be the adult in the room.

This is one of those failures that feels like a minor formatting issue until you remember it’s authentication. Receivers don’t negotiate with authentication. They judge, silently, at scale.

What “too many DNS lookups” actually means

SPF (Sender Policy Framework) is evaluated by the receiving mail server. When they see a message claiming to be from user@yourdomain, they look up your domain’s SPF record (a TXT record starting with v=spf1) and evaluate whether the sending IP is allowed.

During evaluation, certain SPF mechanisms require the receiver to query DNS. The spec limits how many DNS-based mechanisms can be expanded. If evaluation requires more than 10 DNS lookups, the receiver must stop and return permerror (permanent error). “Permanent” here means: don’t bother retrying; the policy is broken.

So “too many DNS lookups” isn’t a warning. It’s the receiver refusing to keep doing your homework.

Important operational detail: the lookup count is not “how many TXT records you personally see.” It’s how many DNS queries the receiver might need after following includes, redirects, and resolving A/MX targets. Includes can explode recursively. One innocent-looking marketing platform can drag in half the SaaS universe.

Joke #1: SPF is the only place where “just one more include” feels harmless until it’s your entire personality and Gmail stops returning your calls.

Facts and context you can use in meetings

  • SPF predates DMARC. SPF started as a way to reduce sender forgery long before DMARC made “alignment” a boardroom word.
  • The 10-lookup limit is deliberate friction. Receivers can’t let senders force unbounded DNS recursion; it’s a resource and abuse-control measure.
  • SPF evaluation happens at the receiver. Your outbound MTA “passing SPF” in its logs is not authoritative. Only the receiver’s evaluation counts.
  • Some mechanisms don’t cost lookups. ip4, ip6, all, and exists semantics matter; only certain ones trigger DNS fetches.
  • Includes are the usual offender. Vendors ship SPF snippets with include: because it’s convenient for them, not because it’s economical for you.
  • Receivers vary in caching and resolver behavior. The spec is clear about the limit, but the path taken to hit it can differ based on DNS caching and recursion settings.
  • SPF errors can be silent deliverability killers. Some receivers treat permerror as fail, others as neutral with weight in spam scoring. Either way, you lose.
  • One domain can have multiple TXT records, but SPF should not. Multiple SPF records at the same name can cause “permerror: multiple SPF records,” a separate but equally irritating failure.

Fast diagnosis playbook

This is the order that finds the bottleneck fastest, without spinning you into a week-long DNS archaeology dig.

First: confirm the failure mode from the receiver’s perspective

  • Look at a real sample of headers from a receiver that rejected or spam-foldered the mail.
  • Extract the SPF result: pass, fail, neutral, softfail, temperror, permerror.
  • If it’s permerror with “too many DNS lookups” (or “exceeded maximum DNS lookups”), you have an SPF expansion problem, not a DNS propagation problem.

Second: compute the lookup count for your SPF record

  • Fetch the current SPF TXT and enumerate mechanisms.
  • Follow include and redirect recursively.
  • Count DNS-triggering mechanisms: include, a, mx, ptr (don’t), exists, redirect.

Third: identify which vendor includes are unnecessary or duplicative

  • List every system that actually sends mail as your domain: your MTA, Microsoft 365/Google Workspace, ticketing, CRM, marketing automation, invoices, HR platform, etc.
  • Map those systems to SPF mechanisms. Remove the ones that do not send as your domain or can be switched to a subdomain.

Fourth: fix with the least risky reduction first

  • Replace a/mx with explicit ip4/ip6 where stable.
  • Collapse redundant includes (some vendors include other vendors you already include).
  • Use subdomains for high-churn senders and align DMARC appropriately.

SPF mechanisms that burn lookup budget

Not everything in SPF costs lookups. The budget is consumed by DNS queries during evaluation.

Mechanisms that typically trigger DNS lookups

  • include: costs at least one lookup for the included domain’s SPF; may cascade.
  • redirect= similar to include in terms of lookups; it transfers evaluation to another record.
  • a and mx: cost lookups to resolve A/AAAA or MX targets and then their A/AAAA.
  • exists: costs a DNS lookup for the generated name.
  • ptr: costs multiple queries and is widely discouraged; many evaluators treat it harshly. Don’t use it.

Mechanisms that do not consume the DNS lookup limit

  • ip4, ip6: direct IP ranges in the record. No DNS required.
  • all: terminator mechanism (-all, ~all, etc.). No DNS required.

Why “only 10” hurts in modern SaaS land

Ten lookups was generous when “your email system” meant one or two MTAs and maybe a backup provider. In 2026, your email footprint is a zoo: the product sends onboarding, finance sends receipts, HR sends policy updates, marketing sends campaigns, and a half-dozen tools send “someone mentioned you” notifications. SPF becomes a shared namespace with no ownership model. That’s how you hit 11 lookups without anyone noticing.

Audit your SPF like an SRE

Don’t treat SPF as a string. Treat it like a dependency graph with failure domains.

Inventory senders, not vendors

Start with “who actually sends mail using @yourdomain in the RFC5321 MAIL FROM (envelope from)?” That’s what SPF evaluates. A vendor can send mail displaying your domain in the From header while using their own envelope domain. In that case SPF for your root domain is irrelevant, and you’re paying lookup budget for nothing.

Separate high-churn senders

Marketing platforms churn IPs and SPF include contents. Transactional MTAs (your own or a stable provider) are relatively steady. Putting everything into one SPF record couples unrelated change rates. Use subdomains to isolate churn: m.yourdomain for marketing, notify.yourdomain for product, billing.yourdomain for finance, etc. Then align DMARC (or use separate DMARC policies per subdomain) based on risk tolerance.

Prefer explicit IPs when you control them

If you operate outbound MTAs with stable egress IPs, use ip4/ip6. Includes are for delegating to a third party. Delegation is convenient, but it’s also giving someone else the right to spend your lookup budget.

Be conservative with “flattening”

Flattening means resolving includes and converting the resulting IP ranges into explicit ip4/ip6 in your record. It reduces lookups, but it creates a maintenance obligation: if the vendor changes IP ranges, you must update your SPF. This is safe only if you can automate it or accept periodic drift risk.

Joke #2: Flattening SPF manually is like hand-editing a routing table: it builds character, mostly in the form of regret.

Practical tasks with commands, outputs, and decisions

These are the field tasks you can run from a Linux box with standard tooling. Each task includes what to look for and the decision to make. Assume you’re testing example.com; swap in your domain.

Task 1: Fetch the domain’s TXT records and spot SPF candidates

cr0x@server:~$ dig +noall +answer TXT example.com
example.com.     300 IN TXT "v=spf1 include:_spf.google.com include:spf.protection.outlook.com -all"
example.com.     300 IN TXT "google-site-verification=abc123"

What it means: SPF is the TXT string starting with v=spf1. If you see more than one v=spf1 TXT at the same name, that’s a different permerror (multiple SPF records).

Decision: Confirm there is exactly one SPF record at the organizational domain (or intentionally at a subdomain). If there are multiple, consolidate first.

Task 2: Check for multiple SPF records (common after “DNS cleanup”)

cr0x@server:~$ dig +short TXT example.com | grep -c "v=spf1"
1

What it means: Count of SPF records returned. Anything above 1 is trouble.

Decision: If >1, merge into a single record and remove the others. Receivers may treat multiple as permerror even if the combined set would be valid.

Task 3: Pull the exact SPF string for parsing

cr0x@server:~$ dig +short TXT example.com | sed 's/"//g' | grep '^v=spf1'
v=spf1 include:_spf.google.com include:spf.protection.outlook.com -all

What it means: You’ve got the raw record content without quotes.

Decision: Save this string in your incident notes. Treat SPF changes like code changes: you want a before/after diff.

Task 4: Enumerate includes quickly

cr0x@server:~$ dig +short TXT _spf.google.com | sed 's/"//g'
v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all

What it means: One include can expand into multiple includes. This is how you run out of budget.

Decision: Build an include graph. If your root record already includes two vendors, and each expands into 3–6 includes, you’re likely near the limit.

Task 5: Check if you’re using expensive mechanisms (mx/a/ptr)

cr0x@server:~$ dig +short TXT example.com | sed 's/"//g' | grep '^v=spf1' | tr ' ' '\n' | egrep '^(a|mx|ptr|exists)'
mx

What it means: This SPF uses mx, which costs DNS lookups (MX + A/AAAA resolution) during evaluation.

Decision: If you don’t need mx/a, remove them. If you do, consider replacing with explicit IP ranges.

Task 6: Inspect MX targets and their A/AAAA records (lookup budget cost)

cr0x@server:~$ dig +noall +answer MX example.com
example.com. 300 IN MX 10 mail1.example.com.
example.com. 300 IN MX 20 mail2.example.com.
cr0x@server:~$ dig +noall +answer A mail1.example.com
mail1.example.com. 300 IN A 203.0.113.10

What it means: If SPF uses mx, the evaluator may need to resolve these names. That consumes lookups.

Decision: If the MX hosts are only for inbound mail and not outbound, don’t use mx in SPF. SPF is for outbound authorization, not inbound routing.

Task 7: Verify what IP your outbound mail actually uses

cr0x@server:~$ grep -R "client-ip" -n /var/log/mail.log | tail -n 3
/var/log/mail.log:98765: ... client-ip=198.51.100.24 ...
/var/log/mail.log:98766: ... client-ip=198.51.100.24 ...
/var/log/mail.log:98767: ... client-ip=198.51.100.24 ...

What it means: Your logs can reveal the egress IP used for SMTP delivery (depends on MTA and logging format).

Decision: If you control the IP and it’s stable, authorize it explicitly with ip4:198.51.100.24 and reduce dependence on DNS mechanisms.

Task 8: Count lookups with a purpose-built SPF checker (local tool)

cr0x@server:~$ spfquery -ip 198.51.100.24 -sender test@example.com -helo mail.example.com
pass (SPF result: pass) smtp.mailfrom=test@example.com

What it means: spfquery evaluates SPF similarly to receivers. Not all builds print lookup counts, but it’s still useful for functional checks.

Decision: Use this to validate that your candidate SPF still passes for known good senders after changes. If it flips to fail/neutral, you broke authorization.

Task 9: Trace DNS resolution paths and TTLs (caching matters)

cr0x@server:~$ dig +trace TXT example.com | tail -n 8
example.com.     300 IN TXT "v=spf1 include:_spf.google.com include:spf.protection.outlook.com -all"
;; Query time: 42 msec
;; SERVER: 192.0.2.53#53(192.0.2.53) (UDP)
;; WHEN: Sat Jan 03 12:00:00 UTC 2026
;; MSG SIZE  rcvd: 164

What it means: You can see TTLs and whether delegation is sane. TTL influences how often receivers need to re-fetch records, but it does not change the 10-lookup hard limit.

Decision: If TTLs are extremely low (like 30s) for SPF-related records, consider raising them to reduce churn and intermittent DNS failures. It won’t fix “too many lookups,” but it reduces temperrors.

Task 10: Detect “SPF record too long” risk when flattening

cr0x@server:~$ dig +short TXT example.com | sed 's/"//g' | grep '^v=spf1' | wc -c
142

What it means: Character count of the current SPF string (roughly). TXT strings have size constraints; providers and receivers may have implementation limits. Also DNS responses can hit UDP size limits if you go wild.

Decision: If flattening would turn your SPF into a 1,800-character IP zoo, reconsider. Shorter isn’t just prettier; it’s more reliably delivered over DNS.

Task 11: Check for accidental recursion via redirect/include loops

cr0x@server:~$ dig +short TXT spf-a.example.com | sed 's/"//g'
v=spf1 include:spf-b.example.com -all
cr0x@server:~$ dig +short TXT spf-b.example.com | sed 's/"//g'
v=spf1 include:spf-a.example.com -all

What it means: This is a loop. Evaluators will hit limits or error out.

Decision: Break the loop immediately. SPF graphs must be acyclic. If you need shared content, use a single shared record included by others, not circular references.

Task 12: Validate that each third-party include is still live and resolvable

cr0x@server:~$ dig +noall +answer TXT spf.vendor-example.net
spf.vendor-example.net. 300 IN TXT "v=spf1 ip4:203.0.113.0/24 -all"

What it means: Vendors occasionally deprecate SPF hostnames. If an include target NXDOMAINs or times out, receivers may return temperror or permerror depending on behavior.

Decision: If the include target doesn’t resolve reliably, remove it or replace with a supported mechanism. Your SPF record should not depend on a vendor’s abandoned DNS name.

Task 13: Spot “include everything” anti-patterns

cr0x@server:~$ dig +short TXT example.com | sed 's/"//g' | grep '^v=spf1' | tr ' ' '\n' | grep '^include:' | sort
include:_spf.google.com
include:mailgun.org
include:spf.protection.outlook.com
include:sendgrid.net
include:spf.salesforce.com
include:spf.zendesk.com

What it means: This domain is trying to authorize half the internet. Some of these services might not even send with your envelope-from.

Decision: Challenge each include with evidence: “Show me a message where the envelope-from is our domain and it came from that provider.” Remove includes that aren’t necessary.

Task 14: Quick check of a candidate reduced SPF before publishing (staging name)

cr0x@server:~$ dig +short TXT spf-test.example.com | sed 's/"//g'
v=spf1 ip4:198.51.100.24 include:spf.protection.outlook.com -all
cr0x@server:~$ spfquery -ip 198.51.100.24 -sender test@spf-test.example.com -helo mail.example.com
pass (SPF result: pass) smtp.mailfrom=test@spf-test.example.com

What it means: You can test a candidate SPF record on a subdomain before changing production. SPF applies per domain name, so you can rehearse.

Decision: Always stage changes when possible. Publish to spf-test, validate, then roll into the real domain during a controlled change window.

Shrink strategies that won’t set your mail on fire

There are only a few honest ways to get under the lookup limit. Anyone promising a magic SPF “compressor” is either flattening, dropping authorization, or hiding lookups somewhere else.

1) Remove what you don’t use (the easiest win)

Most bloated SPF records are carrying dead includes: vendors you churned, pilots you forgot, regional business units doing their own thing. SPF does not have an “unused include” warning. You have to be disciplined.

How to do it safely:

  • Collect a week of outbound samples from each system. Look at the Return-Path and SPF-authenticated identity at receivers.
  • Only keep includes for systems that actually use your domain in the envelope-from.
  • If a vendor sends with their own bounce domain, stop authorizing them at your root domain. It does nothing.

2) Move high-churn senders to subdomains

This is the grown-up solution. It gives you independent SPF records and independent failure domains.

Example:

  • example.com: corporate mail (M365), internal MTAs.
  • m.example.com: marketing platform SPF (and DKIM/DMARC aligned to that subdomain).
  • notify.example.com: product notifications provider.

What to watch: DMARC alignment. If you use DMARC with strict alignment, make sure the visible From domain matches the envelope-from domain or DKIM d= domain appropriately. Otherwise you’ll “fix SPF” and still fail DMARC.

3) Replace mx and a with explicit IPs when stable

mx and a are popular because they’re lazy and self-updating when IPs change. They also cost lookups and can unintentionally authorize hosts you didn’t mean to authorize.

Rule of thumb: If the IP set changes rarely and you can manage it, use ip4/ip6. If the IP set changes often and you can’t automate, don’t flatten; isolate with subdomains instead.

4) Collapse redundant includes

It’s common to include both a “parent” and “child” SPF domain from the same vendor because different setup guides say different things. Sometimes one already includes the other. Sometimes two vendors include the same underlying infrastructure provider. You pay lookup budget twice.

Method: Expand includes and look for overlap. If include:spf1.vendor expands into include:spf2.vendor, you might only need one of them—depending on which product you actually use.

5) Use redirect= when you genuinely want one canonical policy

redirect= is not a lookup cheat; it still costs. What it gives you is policy control: one record becomes authoritative, and other mechanisms are ignored after redirect is applied.

Good use case: you run many vanity domains that should all share the same SPF as your primary outbound domain. You publish minimal records on vanity domains with v=spf1 redirect=example.com and manage the policy in one place.

6) Flatten—only with automation and guardrails

Flattening can be correct when:

  • you have one or two third-party providers,
  • they publish stable IP ranges,
  • you can automatically refresh and republish,
  • you test before rollout.

Flattening is risky when you do it once, by hand, during an incident, and then forget about it for nine months. That’s not engineering. That’s folklore.

7) Don’t “solve” the problem by loosening -all to ~all

Changing the qualifier at the end does nothing for lookup counts. It changes enforcement. Sometimes that’s appropriate during a migration, but it is not a fix for permerror. If you’re getting permerror, the receiver may not even reach the all mechanism.

One operational quote to keep you honest

Paraphrased idea, attribution: W. Edwards Deming argued that you can’t manage what you don’t measure. SPF cleanup is measurement-first work.

Three corporate mini-stories from the trenches

Mini-story 1: The incident caused by a wrong assumption

A mid-size company had been happily running Microsoft 365 for corporate mail and a marketing platform for campaigns. Someone added a new ticketing system that “sends email as your domain,” and the vendor’s onboarding doc said to add another SPF include at the root domain.

The assumption: “SPF includes are cheap, and receivers cache DNS anyway.” That’s not how SPF works. The lookup limit is a hard cap during evaluation; caching might help latency, but it doesn’t give you more than ten lookups.

On Monday morning, password reset emails started landing in spam at a major consumer mailbox provider. Nobody saw bounces. There weren’t many. The provider accepted mail but penalized authentication failures in scoring. The security team saw DMARC aggregate data trending worse, but it lagged and wasn’t tied to an alert.

By noon, the support queue looked like a denial-of-service attack carried out by confused humans. Engineers checked the application, then the MTA, then TLS settings. Eventually someone pasted full headers into chat, and there it was: spf=permerror (too many DNS lookups).

The fix was boring: remove the ticketing system include, because it wasn’t using the company domain as the envelope-from anyway. They enabled DKIM for the ticketing system’s own bounce domain and updated DMARC alignment strategy. Deliverability recovered. The lesson stuck: never approve an SPF include without evidence of envelope-from use.

Mini-story 2: The optimization that backfired

A global org decided to “clean up DNS” and reduce dependency on third parties. Someone proposed flattening all SPF includes into explicit IP ranges at the root domain. It looked elegant: zero includes, minimal lookups, problem solved forever.

They flattened aggressively. The record ballooned with dozens of IP ranges, right up against practical limits for DNS response size. It still published, mostly. Some resolvers started truncating responses. Some receivers retried over TCP and succeeded. Others timed out. The failure mode was intermittent and infuriating.

Worse, one vendor changed their outbound IP ranges. The vendor’s own SPF include would have updated automatically. The flattened record didn’t. Over a weekend, part of the marketing stream started failing SPF, and DMARC began failing for those messages. A “reliability improvement” turned into a maintenance trap.

The recovery plan was to un-flatten for the high-churn providers, move them to subdomains, and keep explicit IPs only for the org’s own MTAs. The resulting design had slightly more lookups than the flattened dream, but it stayed under 10 and didn’t require heroics every quarter.

Mini-story 3: The boring but correct practice that saved the day

A company with a surprisingly mature email posture treated SPF like configuration-as-code. Every DNS change went through review, and they had a simple pre-merge check: compute SPF expansion depth and estimated lookup usage for any modified record.

When the business acquired another brand, marketing requested “just add their platform include to our root SPF so they can send from the main domain.” The engineer on review asked for a sample message and the vendor’s envelope-from behavior. It turned out the platform would use bounces.brand-vendor.tld for SMTP MAIL FROM by default.

They refused the root-domain include. Instead, they set up m.example.com with its own SPF, DKIM, and DMARC policy. The main domain stayed small: Microsoft 365 plus the corporate relays. Lookups stayed under budget. The merger didn’t create a deliverability incident.

No fireworks. No after-hours bridge call. Which is the point.

Common mistakes: symptom → root cause → fix

1) Symptom: “spf=permerror (too many DNS lookups)” in headers

Root cause: SPF evaluation exceeded the 10 DNS-lookup limit due to include chains and/or mx/a mechanisms.

Fix: Remove unused includes; replace mx/a with explicit IPs where appropriate; move senders to subdomains; avoid flattening unless automated.

2) Symptom: SPF sometimes passes, sometimes temperrors

Root cause: DNS timeouts or intermittent NXDOMAIN for included domains; low TTLs; fragile vendor DNS; resolver issues.

Fix: Raise TTLs for your SPF records; remove or replace unreliable includes; ensure your authoritative DNS is healthy; consider redundancy for authoritative nameservers.

3) Symptom: “permerror: multiple SPF records”

Root cause: More than one TXT record at the same owner name starts with v=spf1.

Fix: Merge mechanisms into a single SPF record. Leave unrelated TXT records alone.

4) Symptom: You cut includes and suddenly mail fails SPF for a business-critical system

Root cause: You removed an include that was actually authorizing a sender using your domain in the envelope-from, or you misidentified the domain being checked (root vs subdomain).

Fix: Identify the failing stream from headers; re-authorize the correct provider; consider moving that sender to a dedicated subdomain to prevent future coupling.

5) Symptom: SPF record “looks short,” but still hits lookup limit

Root cause: Nested includes: the record is short because you delegated the complexity elsewhere.

Fix: Expand includes and count lookups across the full dependency tree. Reduce at the source by eliminating includes or isolating senders.

6) Symptom: Receiver says SPF permerror, but your internal checks say pass

Root cause: Different evaluation environment: caching, resolver behavior, or your tool not enforcing the same limits; also possibly checking the wrong identity (MAIL FROM vs HELO).

Fix: Validate against real receiver headers; confirm which domain is evaluated; use multiple tools and confirm lookup expansion.

7) Symptom: After flattening, you get sporadic failures across receivers

Root cause: Oversized SPF TXT responses causing truncation or DNS fragmentation issues; or stale flattened IP ranges.

Fix: Stop flattening everything. Use subdomains for dynamic providers. Keep the root SPF compact and stable.

Checklists / step-by-step plan

Change plan: shrink SPF without breaking mail

  1. Collect evidence: For each outbound system, capture sample headers from at least two receivers (one consumer, one corporate). Identify the envelope-from domain and sending IP.
  2. Inventory current SPF dependencies: Expand include and redirect targets; list all domains involved.
  3. Count lookup consumers: Identify mechanisms that cause DNS queries (include, a, mx, exists, redirect). Estimate worst-case.
  4. Remove dead weight: Delete includes for vendors that do not use your domain as MAIL FROM.
  5. Isolate churn: Create subdomains for marketing/notification platforms and move sending identities there. Publish separate SPF per subdomain.
  6. Prefer explicit IPs for owned MTAs: Replace a/mx with ip4/ip6 for stable outbound IPs.
  7. Stage the record: Publish candidate SPF to spf-test.example.com and run checks for all expected sender IPs.
  8. Roll out with a clock: Make production DNS change during a window; keep TTL in mind (if TTL is 300s, expect a few minutes to converge, but plan for longer).
  9. Monitor receiver signals: Watch deliverability metrics, bounces, and DMARC aggregate trends. Confirm SPF results in sampled headers.
  10. Document ownership: Make SPF changes gated by a single team or process. “Anyone can add an include” is how you end up here again.

Operational checklist: before approving a new SPF include

  • Do we have a header sample proving the vendor uses our domain in the envelope-from?
  • How many lookups will this include add when expanded (including nested includes)?
  • Can we use a subdomain instead of the root domain?
  • Can we authorize by IP (if stable) instead of delegating via include?
  • Is DKIM configured for the visible From domain to keep DMARC happy even if SPF has issues?
  • What’s the rollback plan (previous TXT value saved, TTL known)?

FAQ

1) What exactly counts toward the 10 DNS lookup limit?

Mechanisms that require DNS queries during evaluation: include, redirect, a, mx, ptr, and exists. The limit is on the number of such DNS-interactive mechanisms evaluated, including those pulled in via includes.

2) If I increase TTL, will it fix “too many DNS lookups”?

No. TTL can reduce DNS timeouts and improve stability, but it does not change the spec’s hard cap of 10 lookups. It can help with temperror, not permerror due to lookup count.

3) Is redirect= better than include: for lookup limits?

Not inherently. Both can cost lookups. redirect is useful for centralizing policy, especially for many domains sharing one SPF. It’s not a lookup budget loophole.

4) Why not just switch -all to ~all?

Because lookup-limit failures often prevent the evaluator from reaching the all mechanism at all. Even when it does, changing enforcement doesn’t reduce lookups. It just lowers your spoofing resistance.

5) Can I publish SPF in multiple TXT records and have receivers combine them?

No. Multiple SPF records at the same name usually result in permerror. You can have multiple TXT records for other purposes, but only one should be your SPF policy.

6) Should I flatten SPF?

Sometimes. Flattening is appropriate when you can automate refresh and publishing, and when the resulting record stays within practical DNS size limits. If you can’t automate, prefer subdomains and fewer includes.

7) How do subdomains help with the lookup limit?

The lookup limit applies per SPF evaluation. If marketing sends using bounce@m.example.com, the receiver evaluates SPF for m.example.com, not example.com. That gives you separate 10-lookup budgets and isolates changes.

8) What if we must use many providers and can’t get under 10?

Then you need architecture, not heroics: consolidate providers, move streams to subdomains, and ensure DKIM is strong so DMARC can pass even when SPF is constrained. Also review whether some systems can stop using your domain as envelope-from.

9) Does IPv6 make this easier or harder?

Neither, directly. ip6 mechanisms don’t cost DNS lookups. But dual-stack providers can increase record size if you flatten everything. Keep it tidy and only authorize what you use.

10) What’s the difference between SPF failing and SPF permerror?

Fail means the record was evaluated and the IP wasn’t authorized. Permerror means the record itself is broken (too many lookups, multiple records, invalid syntax). Permerror is often treated as a serious negative signal.

Conclusion: next steps that stick

Fixing “SPF too many DNS lookups” is less about cleverness and more about refusing to let your root domain become a dumping ground for every SaaS onboarding checklist. Keep the root SPF small, stable, and owned. Push churn to subdomains. Use explicit IPs where you control them. Delegate only when you must—and count the cost.

Next steps:

  1. Pull your current SPF and expand every include into a dependency list.
  2. For each include, prove it’s needed with real headers showing your domain in MAIL FROM.
  3. Move marketing and high-churn senders to dedicated subdomains with their own SPF/DKIM/DMARC.
  4. Replace mx/a mechanisms with ip4/ip6 for stable outbound MTAs.
  5. Stage and test on a subdomain, then roll out with a rollback plan and monitoring.
← Previous
Infinity Fabric: the invisible link that can make-or-break performance
Next →
Docker containerd/runc errors: how to debug without reinstalling

Leave a comment