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:
| Mechanism | How to resolve it | Result |
|---|---|---|
include: | Fetch the target’s SPF record and expand its mechanisms recursively | ip4:/ip6: for every IP it authorizes |
a | Resolve the domain’s A/AAAA records | One ip4:/ip6: per address |
mx | Resolve MX records, then the A/AAAA of each mail host | ip4:/ip6: for each MX host IP |
ptr | Do not flatten — it’s deprecated, slow, and unreliable | Remove it |
exists: | Usually can’t flatten (depends on runtime macros) | Keep as-is or isolate to a subdomain |
ip4/ip6 | Already static | Keep 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.comthat 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.