← Blog
October 8, 2026 Esteve Castells 14 min

SPF Flattening: Why You Need It and How to Do It

SPF has a hard 10-DNS-lookup limit. Most organizations hit it by their fourth or fifth email service. SPF flattening replaces include chains with static IP addresses to stay under budget, but it creates operational risks you need to manage.

SPFEmail SecurityDNSDeliverabilityEmail Infrastructure

SPF has a hard limit that most people discover the hard way: 10 DNS lookups per evaluation. Every `include`, `a`, `mx`, `redirect`, and `exists` mechanism in your SPF record costs one lookup, and the count is recursive. When your record includes a vendor and that vendor's SPF includes two more domains, all three lookups come out of your budget. Hit 11 and the entire SPF check returns permerror. Not softfail. Not neutral. A hard evaluation failure that tells receiving servers your SPF record is broken.

Most organizations reach this limit the moment they add their fourth or fifth email service. Google Workspace, a transactional sender, a marketing platform, a CRM, a helpdesk system. Each one comes with its own include directive and its own nested dependencies. The math stops working quietly, and the first sign is usually a spike in delivery failures that nobody connects to the SPF record because the record itself looks perfectly valid.

SPF flattening is the technique that solves this by replacing include chains with the actual IP addresses those chains resolve to. Instead of asking DNS to walk through nested includes at evaluation time, you paste the final IP ranges directly into the record. The receiver gets the same authorization answer without spending any DNS lookups. But flattening introduces its own operational risks, and understanding when to flatten versus when to restructure is the difference between a quick fix and a ticking time bomb.

Start here: Run your domain through the SPF Builder to see your current lookup count, or use the Email Security Check to audit SPF alongside DKIM and DMARC in one pass.

The 10-Lookup Problem in Detail

The lookup limit exists because SPF evaluation happens on the receiving server's side during the SMTP transaction. RFC 7208 caps the number of DNS-querying mechanisms at 10 to prevent a single inbound message from triggering an unbounded chain of DNS queries. The intent is reasonable: without a cap, a malicious SPF record could force a receiver into dozens or hundreds of recursive lookups, effectively turning SPF evaluation into a denial-of-service vector.

The problem is that 10 lookups is not a generous budget. Consider a domain that sends through six common services, each of which publishes its own SPF include chain:

v=spf1
  include:_spf.google.com           ← Google Workspace
  include:sendgrid.net              ← Transactional email
  include:_spf.salesforce.com       ← CRM
  include:spf2.hubspot.com          ← Marketing automation
  include:mail.zendesk.com          ← Helpdesk
  include:servers.mcsv.net          ← Mailchimp newsletters
  ~all

Lookup count (including nested includes):
  _spf.google.com      → 1 + 1 nested  = 2
  sendgrid.net         → 1 + 0 nested  = 1
  _spf.salesforce.com  → 1 + 2 nested  = 3
  spf2.hubspot.com     → 1 + 1 nested  = 2
  mail.zendesk.com     → 1 + 0 nested  = 1
  servers.mcsv.net     → 1 + 1 nested  = 2
                              Total:    11  ← permerror

Eleven lookups. One over the limit. The record is syntactically perfect. Every include points to a real, active vendor. But any receiver that evaluates this record according to spec will return permerror, which means SPF fails for every single message sent from this domain. Not just messages from Mailchimp. All of them. The evaluation aborts the moment the budget is exceeded, regardless of which mechanism would have matched.

The arithmetic gets worse because you do not control the nested lookups. If Google adds another nested include to `_spf.google.com` tomorrow, your record goes from 10 lookups to 11 without any change on your side. You published the same TXT record you published last month, but now it fails because a vendor changed their infrastructure. This is the core fragility of SPF at scale: the lookup budget is shared between your record and every vendor's record, and you have no contractual or technical guarantee that vendors will keep their nesting depth stable.

What SPF Flattening Does

SPF flattening resolves every include chain to its terminal IP addresses and replaces the include mechanisms with `ip4` and `ip6` mechanisms that list those addresses directly. Since `ip4` and `ip6` cost zero DNS lookups, the flattened record can authorize the same set of senders while staying well under the 10-lookup limit.

Here is a before-and-after comparison for a domain that sends through Google Workspace and SendGrid:

# BEFORE flattening (3 DNS lookups)
v=spf1 include:_spf.google.com include:sendgrid.net ~all

# _spf.google.com resolves to:
#   ip4:35.190.247.0/24  ip4:64.233.160.0/19  ip4:66.102.0.0/20
#   ip4:66.249.80.0/20   ip4:72.14.192.0/18   ip4:74.125.0.0/16
#   ip4:108.177.8.0/21   ip4:173.194.0.0/16   ip4:209.85.128.0/17
#   ip4:216.58.192.0/19  ip4:216.239.32.0/19
#
# sendgrid.net resolves to:
#   ip4:167.89.0.0/17  ip4:208.117.48.0/20  ip4:50.31.32.0/19
#   ip4:198.37.144.0/20

# AFTER flattening (0 DNS lookups)
v=spf1
  ip4:35.190.247.0/24   ip4:64.233.160.0/19  ip4:66.102.0.0/20
  ip4:66.249.80.0/20    ip4:72.14.192.0/18   ip4:74.125.0.0/16
  ip4:108.177.8.0/21    ip4:173.194.0.0/16   ip4:209.85.128.0/17
  ip4:216.58.192.0/19   ip4:216.239.32.0/19
  ip4:167.89.0.0/17     ip4:208.117.48.0/20  ip4:50.31.32.0/19
  ip4:198.37.144.0/20
  ~all

The flattened record authorizes exactly the same IP ranges as the original. A message from `209.85.128.50` passes SPF either way. The difference is purely mechanical: the receiver does not need to perform any DNS lookups to evaluate the flattened version because every mechanism is an IP range that can be checked locally. The lookup count drops from 3 to 0.

This is the appeal of flattening. You can authorize six, eight, or twelve vendors in a single SPF record without touching the 10-lookup limit, because the limit only applies to mechanisms that require DNS resolution. The cost is paid elsewhere, and that cost is the entire reason flattening is not a set-and-forget solution.

Static vs Dynamic Flattening

There are two approaches to flattening, and the distinction matters more than most teams realize when they first encounter the technique.

Static Flattening

Static flattening means manually resolving each vendor's SPF record, copying the resulting IP ranges, and pasting them into your TXT record. You run the resolution once, publish the result, and move on. This is the approach most people try first because it requires no tooling and produces an immediate fix.

The problem is that the IPs you resolved today may not be the IPs the vendor uses next month. Email service providers add, remove, and rotate sending IP ranges as their infrastructure scales. Google's SPF record, for example, has changed its IP ranges dozens of times since 2020. If you statically flattened `_spf.google.com` in January and Google added a new sending range in March, every message sent from that new range will fail SPF on your domain. The flattened record has no way to know about IP ranges that did not exist when you resolved it.

Dynamic Flattening

Dynamic flattening automates the resolution process. A service or script periodically resolves each vendor's include chain, compares the result against what is currently published, and updates your DNS record whenever the IP ranges change. The resolution might run every hour, every six hours, or every day depending on how frequently your vendors rotate infrastructure.

Several tools implement dynamic flattening: AutoSPF and SPF Proxy are dedicated services, and DomScan's SPF Builder shows flattened output alongside the include-based version so you can see exactly which IPs each vendor resolves to. The operational requirement is the same regardless of tooling: someone or something must watch for changes and update the record before the old IPs go stale.

Dynamic flattening is the only viable approach for production domains. Static flattening is acceptable for testing or for domains with a single, stable vendor, but any domain that sends through multiple providers needs automated resolution and update. The window between a vendor changing IPs and your record becoming stale is the window during which legitimate mail fails SPF.

The Risks of Flattening

Flattening solves the lookup limit problem, but it introduces a different set of operational risks that are easy to underestimate. Every team considering flattening should understand these before committing to the approach.

Vendor IP Changes

This is the primary risk. When you use `include:_spf.google.com`, you are delegating authorization to Google's current infrastructure, whatever it happens to be at evaluation time. When you flatten that include into static IP ranges, you are asserting that you know exactly which IPs Google uses to send mail. The moment Google adds a new sending range that is not in your flattened record, mail from that range fails SPF on your domain. The failure is silent on Google's side because they have no visibility into your DNS record. You discover it when recipients stop receiving mail or when DMARC aggregate reports show SPF failures from IP addresses you do not recognize.

DNS Record Size Limits

A flattened record that covers five or six vendors can easily contain 30 or more IP ranges. Each `ip4` or `ip6` mechanism takes 15 to 25 bytes, and a DNS UDP response has a practical limit of 512 bytes (or 4096 bytes with EDNS0). Exceeding these limits causes truncation or fallback to TCP, which some resolvers handle poorly. If the record is too large for a single TXT entry, you need to split it across subdomains using include mechanisms to reference the overflow, which partially reintroduces the lookup cost you were trying to eliminate.

Maintenance Burden

Without automation, a flattened record decays. Every vendor change, every infrastructure migration, every IP range rotation creates a gap between what your record authorizes and what your vendors actually use. The decay is invisible until mail starts failing, and the debugging process is harder because the record contains raw IP ranges instead of named includes. When you see `include:sendgrid.net` in a record, you know that mechanism covers SendGrid. When you see `ip4:167.89.0.0/17`, you need to look up which vendor owns that range before you can decide whether to keep or remove it.

Debugging Difficulty

An include-based SPF record is self-documenting. Each mechanism names the vendor it authorizes. A flattened record is a wall of IP ranges with no context about why each range is there. When a new team member needs to audit the record, or when a security review asks which vendors are authorized to send mail, a flattened record requires reverse engineering that an include-based record answers at a glance. Some teams mitigate this by adding comments in their DNS management interface or by maintaining a separate document that maps IP ranges to vendors, but both approaches rely on discipline that frequently lapses.

Alternative Approaches to the Lookup Limit

Flattening is not the only way to stay under 10 lookups. Several alternative techniques reduce lookup consumption without replacing includes with raw IPs, and they are worth considering before committing to a flattening strategy.

Subdomain Delegation

Instead of authorizing every sender on `example.com`, move different mail streams onto dedicated subdomains. Marketing email sends from `mail.example.com`. Transactional notifications send from `notify.example.com`. Each subdomain gets its own SPF record with its own 10-lookup budget. The parent domain's SPF record only needs to cover the services that actually send as `example.com`, which is typically just the primary email platform.

Subdomain delegation does not reduce the total number of DNS lookups across all your domains. It redistributes the budget so that no single domain exceeds the limit. This is the approach that scales best for organizations with many sending services, and it has the secondary benefit of isolating reputation: if a marketing campaign triggers spam complaints, the reputation impact lands on `mail.example.com` rather than on the parent domain that handles business correspondence.

Remove Stale Vendors

Many SPF records contain includes for vendors the organization stopped using years ago. The Mailchimp include that was added for a 2022 campaign. The Zendesk include from a support platform that was replaced by Freshdesk. Every stale include costs a lookup and delivers no value. Auditing the SPF record against current vendor contracts is the simplest way to recover lookup budget, and it costs nothing.

Use the DNS Lookup Tool to query your current TXT records and cross-reference each include against your active email senders. The Email Security Check flags includes that resolve to empty or defunct SPF records, which is a strong signal of a stale vendor.

Use ip4/ip6 for Stable Infrastructure

If you operate your own mail servers on static IP addresses, there is no reason to use an `a` or `mx` mechanism that costs a lookup. Replace `a:mail.example.com` with `ip4:203.0.113.25` and you eliminate one lookup for infrastructure you control and that rarely changes. This approach only works for IPs you own and manage directly. Applying it to vendor IPs is just manual static flattening with all its associated risks.

Eliminate Void Lookups

RFC 7208 also limits void lookups to two. A void lookup occurs when a DNS-querying mechanism returns an empty answer or NXDOMAIN. Stale includes that point to decommissioned domains are the usual cause. Removing them recovers both regular lookup budget and void lookup budget. Two void lookups trigger permerror just as reliably as exceeding 10 total lookups, and they are harder to diagnose because the mechanism text looks valid.

When to Flatten vs When to Restructure

Flattening is a tactical fix. It buys time by compressing lookup consumption, but it does not address the underlying architectural problem: too many sending services authorized on a single domain. The decision framework is straightforward.

  • If you have 3 to 5 senders and are at 9 or 10 lookups, flattening one or two high-nesting vendors is a reasonable and low-risk approach. Flatten the vendor with the deepest include chain and monitor for IP changes.
  • If you have 6 or more senders on one domain, the real fix is subdomain isolation. Flattening 6 vendors produces a record so large and opaque that maintenance becomes its own operational risk. Split by mail class: transactional, marketing, support, corporate.
  • If you are adding a new vendor and the record is already at 10 lookups, do not flatten just to make room for one more include. That path leads to a record that is perpetually at capacity. Move the new vendor onto a subdomain instead.
  • If your organization sends from a single platform with one or two includes, you do not need flattening at all. The 10-lookup problem only becomes real when multiple vendors share the same domain.

The worst outcome is treating flattening as permanent architecture. Teams flatten to solve an immediate problem, the flattened record works, and nobody revisits the decision. Two years later the record contains 40 IP ranges from vendors that have been replaced, and nobody knows which ranges are active. Flattening should always be paired with a timeline for restructuring, even if that timeline is six months out.

A Practical Flattening Workflow

If flattening is the right choice for your situation, here is the workflow that minimizes operational risk.

  1. Inventory your senders: list every service that sends email as your domain, including services that teams may have onboarded without updating DNS.
  2. Resolve each vendor's include chain: use the SPF Builder to see the full lookup tree and the terminal IP ranges for each vendor. Document which IPs belong to which vendor.
  3. Decide which includes to flatten: flatten the vendors with the deepest nesting first, as they consume the most lookups. Keep includes for vendors whose IP ranges change frequently if your automation is not yet in place.
  4. Publish the flattened record: replace the selected includes with their resolved ip4 and ip6 mechanisms. Keep the remaining includes as-is. Verify the total lookup count is under 10.
  5. Set up monitoring: use automated resolution on a schedule (daily at minimum) to detect when a vendor's IP ranges change. Alert when a change is detected so you can update the flattened record before mail starts failing.
  6. Plan the restructuring: document which senders should move to subdomains, set a timeline, and migrate them one at a time. Each migration recovers lookup budget on the parent domain.

The SPF Builder handles steps 2 through 4 by showing the full include tree, the resolved IPs per vendor, and the resulting lookup count for any combination of flattened and unflattened mechanisms. The DMARC Builder helps you verify that your DMARC alignment still holds after restructuring, since moving senders to subdomains affects SPF alignment unless the DMARC policy uses relaxed alignment mode.

Flattening and DMARC Interaction

Flattening does not change the SPF result from a DMARC perspective. If a message passed SPF before flattening, it will pass after flattening, because the authorized IP ranges are identical. The risk is in the other direction: if flattening causes a legitimate IP to be omitted (because the record was not updated after a vendor change), SPF fails and DMARC alignment fails with it.

This matters most for domains running DMARC with `p=reject`. A flattened SPF record that goes stale will cause legitimate mail to be rejected, not just flagged, if DKIM also fails or is not configured for that sender. The combination of SPF flattening and DMARC reject is operationally aggressive and requires robust monitoring to maintain safely.

For domains still in DMARC `p=none` or `p=quarantine`, a stale flattened record produces DMARC failures in aggregate reports without immediately blocking mail. This gives you a window to detect and fix the problem before it affects delivery. Use the Email Security Check to verify your current DMARC policy and alignment status.

SPF flattening is one of those techniques that is simple to execute and difficult to maintain. The initial fix takes fifteen minutes. The ongoing discipline of monitoring vendor IP changes, updating records, documenting which ranges belong to which sender, and planning the eventual migration to subdomains is what separates teams that use flattening successfully from teams that discover six months later that half their mail is failing SPF. Treat it as a bridge, not a destination, and you get the lookup budget relief without the long-term fragility.

For a deeper look at SPF record structure, see SPF Record Best Practices. For guidance on how SPF interacts with DKIM and DMARC, see SPF, DKIM and DMARC Explained. For a diagnostic check on your current SPF record, see SPF Record Check.

Independent references: Review RFC 7208 for the SPF specification and the 10-lookup limit, and Google Sender Guidelines for current authentication requirements for bulk senders.

Key Takeaways

  • Every include, a, mx, redirect, and exists mechanism in an SPF record costs one DNS lookup against a hard limit of 10. Exceeding it causes permerror and total SPF failure.
  • SPF flattening replaces vendor include chains with resolved IP ranges, eliminating DNS lookups but requiring automated updates when vendors change their sending infrastructure.
  • Flattening is a tactical fix. If your domain has six or more sending services, subdomain isolation is the structural solution that eliminates the lookup budget problem entirely.

Related Articles