Skip to main content
New SPF lookups must resolve in milliseconds — why a DMARC tool's add-on isn't enough Learn Why → →

How to flatten an SPF record

To flatten an SPF record, resolve every lookup-causing mechanism (include, a, mx) into explicit ip4/ip6 addresses, deduplicate and aggregate the ranges, then publish one record under the RFC 7208 10-lookup limit.

Flattening an SPF record means replacing the mechanisms that trigger DNS lookups — include:, a, mx, exists, ptr, and redirect — with the explicit ip4: and ip6: ranges they resolve to. The result is a record that authorizes the exact same senders but forces receiving servers to walk far fewer (ideally zero) DNS queries, keeping you safely under the RFC 7208 10-lookup limit. This guide walks through the process step by step, shows what a flattened record looks like, and explains how to keep it accurate once it’s live.

This page is part of our larger guide to SPF flattening. If you want to skip the manual work entirely, the SPF Checker expands every include and counts your lookups in seconds.

Why you’d flatten an SPF record in the first place

SPF authentication is capped at 10 DNS lookups per evaluation under RFC 7208. Every include:, a, mx, exists, and redirect term counts against that budget, and each one can trigger further recursive lookups inside the domain it points to. Add a marketing platform, a CRM, a helpdesk, and an invoicing service, and a single v=spf1 record can quietly balloon to 15-40 lookups.

When you cross the limit, receivers return a PermError. A PermError doesn’t just fail one message — it invalidates the whole record, so legitimate mail from every authorized source can start failing SPF. Because nothing bounces loudly, teams often don’t notice until a customer reports a missing invoice or password-reset email.

Flattening solves this by resolving those indirect mechanisms ahead of time and publishing the raw IPs. A receiver evaluating a fully flattened record does simple IP matching with no recursive DNS traversal, which also means faster validation and no exposure to a third party’s temporary DNS outage.

What a flattened SPF record looks like

Here is a typical unflattened record that leans on three includes:

v=spf1 include:_spf.google.com include:vendor.com include:vendor2.net -all

Each include is at least one lookup, and Google’s include alone nests several more. Flattened, the same authorization becomes a direct list of IPs:

v=spf1 ip4:203.0.113.5 ip4:192.168.1.1 ip4:185.23.45.67 -all

No lookups happen at evaluation time because every authorized address is already spelled out. The -all qualifier is preserved so the policy stays strict.

How to flatten an SPF record, step by step

Step 1: Find and audit your current record

Pull your existing SPF record with a dig TXT yourdomain.com query (or your DNS provider’s dashboard) and confirm you have exactly one v=spf1 TXT record. Multiple SPF records on the same name are themselves a PermError. Note which mechanisms cause lookups (include, a, mx, exists, redirect, ptr) versus the cost-free ip4/ip6 entries you can keep as-is.

Step 2: Count your lookups

Before changing anything, measure how far over budget you are. Run your domain through the SPF Checker, which recursively expands every include and gives you an exact lookup count. If you’re at 8 or more, or already seeing PermError, flattening (or delegation) is warranted. If you’re at 3 or fewer stable includes, you may not need to flatten at all.

Step 3: Recursively resolve each mechanism to IPs

This is the core of flattening. For every lookup-causing term, resolve it down to explicit addresses:

MechanismHow to resolve itResult
include:Fetch the target’s SPF record and expand its mechanisms recursivelyip4:/ip6: for every IP it authorizes
aResolve the domain’s A/AAAA recordsOne ip4:/ip6: per address
mxResolve MX records, then the A/AAAA of each mail hostip4:/ip6: for each MX host IP
ptrDo not flatten — it’s deprecated, slow, and unreliableRemove it
exists:Usually can’t flatten (depends on runtime macros)Keep as-is or isolate to a subdomain
ip4/ip6Already staticKeep unchanged

Walk the graph depth-first and track which domains you’ve already visited so you can detect circular includes — if an include points back to a domain already on your resolution stack, stop and keep it as an include rather than looping forever.

Step 4: Deduplicate and aggregate CIDRs

Recursive expansion produces overlaps. Two vendors may share an IP, or you may collect several adjacent /25 blocks that combine cleanly into a /24. Deduplicate every address, then aggregate adjacent ranges into supernets only when the union stays entirely inside one provider’s authorized space. Over-aggregating across unrelated providers authorizes IPs you don’t control — a security regression, not an optimization.

Step 5: Watch the record size

DNS TXT strings are limited to 255 characters per quoted segment; longer records must be split into multiple concatenated strings within the same record. As a practical rule, keep the total response under roughly 450-900 bytes to avoid UDP fragmentation and middlebox problems. If the flattened list is too big, split IPs into helper labels (e.g. spf-a.example.com, spf-b.example.com) that each hold only ip4/ip6 entries and include them from the main record — each helper costs one lookup, so keep the total ≤ 10.

Step 6: Re-attach the all qualifier and validate

Append your original terminating mechanism — -all for strict enforcement is recommended for production senders. Then re-run the record through an SPF validator to confirm the syntax is clean, there’s still only one record, and the lookup count is where you expect. If you’re migrating cautiously, you can publish with ~all briefly, then switch to -all once monitoring shows stable pass rates.

Step 7: Publish with a low TTL, then raise it

Before you publish, lower the record’s TTL to 60-300 seconds so any mistake can be corrected quickly. Publish the new flattened record, verify it resolves correctly from multiple public resolvers (Google, Cloudflare, Quad9), and watch your DMARC aggregate reports for any dip in SPF pass rates. Once things are stable, raise the TTL back to 1-4 hours.

The catch: flattened records go stale

Here’s the problem that trips up most people who flatten by hand. The moment you flatten, your record is a snapshot. When Google, Mailchimp, Amazon SES, or any other provider rotates their sending IPs — and large ESPs do this constantly — your hardcoded list no longer matches reality. Mail from the new IPs silently fails SPF, and you’re back to lost invoices and failed password resets, except now the cause is invisible because the record looks fine.

CDN-backed and marketing senders are the worst offenders: internal AutoSPF data across 1,200+ domains shows CDN-backed senders churning 8-15% of their IP set monthly, versus under 0.5% for in-house mail servers. Flattening a high-churn provider blindly is asking for trouble.

The practical takeaways:

  • Flatten stable sources (on-prem relays, static cloud IPs) aggressively.
  • Leave volatile ESPs as includes, or isolate them behind a delegated subdomain like mail-out.example.com that the root includes with a single lookup.
  • Never treat flattening as one-and-done — it needs continuous re-resolution.

Automate re-flattening with AutoSPF

Doing steps 1-7 by hand every time a vendor changes IPs isn’t realistic. This is exactly what AutoSPF’s automated SPF flattening service is built for. It runs the deterministic flattening algorithm above continuously: it re-scans your includes every 15 minutes, and when an upstream provider’s IPs change, it auto-updates your published record through your DNS provider’s API — with atomic swaps, staged TTLs, and one-click rollback if a canary check fails.

Critically, AutoSPF resolves to the exact same IPs your includes resolve to — it never widens authorization with over-broad CIDR merges, so you don’t accidentally authorize senders you didn’t intend to. You keep a small, stable record at the root; AutoSPF keeps it correct in the background.

To decide which of your sources to flatten versus delegate, see our guide on the best SPF flattening tools. If you’d rather avoid hardcoding IPs altogether, compare the approaches in SPF flattening vs macros. And before you flatten, it’s worth confirming the change won’t disturb your other authentication records — see does SPF flattening affect DKIM & DMARC.

Frequently Asked Questions

Does flattening an SPF record break DKIM or DMARC?

No, when done correctly. Flattening only changes which IPs SPF authorizes — it doesn’t touch DKIM signatures or DMARC alignment. The risk is indirect: if a stale flattened record starts failing SPF for legitimate mail, that can drag down DMARC pass rates. Keep the record re-resolved and both stay healthy.

How many DNS lookups does a flattened SPF record use?

A fully flattened record uses zero DNS lookups at evaluation time because every authorized IP is listed explicitly as ip4:/ip6:. If you keep a few volatile includes or split IPs into helper labels, each of those adds one lookup — just keep the total at or under the RFC 7208 limit of 10.

Can I flatten ptr and exists mechanisms?

Generally no. ptr is deprecated, slow, and should simply be removed. exists: typically relies on runtime macros (evaluating MAIL FROM or HELO at check time), so it can’t be reduced to a static IP list. Keep exists as-is, or isolate it to a delegated subdomain to limit its lookup impact.

How often does a flattened SPF record need updating?

As often as your senders change their IPs. In-house mail servers may be stable for weeks, but major ESPs and CDNs can change addresses daily. That’s why manual flattening is fragile and AutoSPF re-scans every 15 minutes, publishing an updated record automatically whenever an upstream IP set changes.

What happens if my flattened record gets too big?

DNS TXT records are limited to 255 characters per string, and oversized records risk UDP fragmentation. If the flattened IP list is too large, split it into helper labels (each holding only ip4/ip6 entries) and include them from the main record, or delegate volatile providers to a subdomain. Aim to keep the total response under ~900 bytes and lookups ≤ 10.

Should I flatten my SPF record manually or use a tool?

Manual flattening works for a one-time fix, but it can’t keep up with providers rotating IPs — a hand-flattened record silently de-authorizes senders as soon as an upstream range changes. A managed tool like AutoSPF handles the recursive resolution, deduplication, size management, and continuous re-flattening for you, which is why it’s the recommended approach for anything beyond a single static sender.

Rated 5/5 on G2 · Trusted since 2018

Trusted by 50,000+ domains

"AutoSPF Flattens SPF Records Seamlessly & Keeps Changes Logged - I am quite pleased with the product"

It does what it promises to do, and does it very well. I appreciate that it keeps a log of changes made, which prevents many mistakes. A client's SPF record would have way too many lookups, but AutoSPF makes that problem go away. The length of the SPF record is typically not the issue; it's the amount of lookups in the record that are. AutoSPF "flattens" the record, automatically expanding the defined lookups to IP addresses or ranges. And it auto-updates the record when the un-flattened lookups change.
PJ

Peter J.

President · Small-Business (50 or fewer emp.)

"Helped us go beyond capacity"

AutoSPF did exactly as described, it helped us get past our 10 lookup limit. Afterwards, we hit another limit regarding overall capacity and when contacted, they quickly provided us with a new solution to eliminate capacity issues entirely going forward, so now we can add as many SPF records as needed. They also provided us with a personalized support video explaining their new method in its entirety using our instance as the example.
VU

Verified User

Financial Services · Mid-Market (51-1000 emp.)

"Great service and great support"

AutoSPF was easy to initially set up on our own and a great cost effective entry into spf flattening. Needed our first support assistance today and got great response including a video demonstrating the issue I was trying to solve, a quick fix, and more detailed followup.
GF

Greg F.

Mid-Market (51-1000 emp.)