Email authentication
SPF Flattening: When You Need It and How to Do It Right [2026]
TL;DR: SPF flattening replaces nested include: mechanisms with hardcoded ip4: / ip6: ranges to stay under the 10 DNS lookup limit that RFC 7208 imposes. It works, but the trade-off is staleness — when a sender changes their IPs, your flattened record breaks and your mail starts failing SPF. The right answer depends on whether you can keep the record updated. Most readers should audit and reduce senders before flattening anything.
Why flattening exists (the 10-lookup limit, briefly)
SPF imposes a hard ceiling: receivers are required to abandon evaluation after 10 DNS-querying mechanisms (RFC 7208 §4.6.4). Cross that ceiling and your record returns permerror, your DMARC alignment via SPF collapses, and — depending on your policy — mail can be quarantined or rejected.
The mechanisms that count: include, a, mx, ptr, exists, and redirect. The mechanisms that don't count: ip4, ip6, and all. That asymmetry is the entire reason flattening exists. By rewriting everything that triggers a DNS query into static IP literals, you eliminate the lookup overhead and the limit becomes irrelevant.
For the deep dive on what permerror actually does to your deliverability and how to diagnose it, see /learn/spf-permerror. This page assumes you already know you're over the limit and you're trying to figure out what to do about it.
Static flattening (DIY)
Static flattening is the do-it-yourself path. You take your existing record, recursively resolve every include: down to the underlying IP ranges, and publish those IPs directly. The result is a single SPF record with zero include: mechanisms and a long list of ip4: / ip6: literals. Lookup count drops to zero. Permerror solved.
The mechanics are straightforward. Several open-source flatteners will produce a flattened record from your existing one in seconds. The most-cited references in the deliverability community are Scott Kitterman's SPF Record Testing Tools (which is a validator, not a flattener — useful for confirming the result) and the assorted spf-tools repositories on GitHub that automate the resolution-and-rewrite step. Some deliverability operators script this themselves with a few dig calls and a sort step; if you're comfortable on the command line, that's also fine.
What you publish looks something like this (truncated):
v=spf1 ip4:35.190.247.0/24 ip4:64.18.0.0/20 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:104.16.0.0/13
ip4:108.177.8.0/21 ip4:172.217.0.0/19 ip4:173.194.0.0/16 ip4:209.85.128.0/17
ip4:216.58.192.0/19 ip4:216.239.32.0/19 ... -allThat's the shape. Lookup count: zero.
The fundamental tradeoff with static flattening is staleness. Your record breaks the moment a sender changes their IPs and you didn't update. Microsoft 365 quietly adds a netblock to spf.protection.outlook.com on a Tuesday afternoon. Your flattened record doesn't know. By Wednesday, mail from the new netblock is failing SPF, and you find out via the angry customer support thread on Friday. This isn't theoretical — it's the most common failure mode for static flattening, and the reason most deliverability teams stop doing it after the first incident.
If you go static, treat the record as a maintained pipeline, not a one-time fix. That means: a quarterly cron job that re-resolves your underlying senders' SPF records, diffs the result, and either auto-publishes or files a ticket if the diff exceeds a threshold. If you're not going to build that pipeline, static flattening is borrowed time.
Dynamic flattening (managed services)
Dynamic flattening is the managed-service version. Instead of publishing IP literals in your own zone, you publish a single include: that points at a vendor's hosted SPF record. The vendor takes care of resolving your downstream senders, watching for IP changes, and regenerating the served record on a nightly or on-change cadence. Some vendors use SPF macros (%{i}, %{s}, etc.) to encode telemetry into the served record — this is the "macro-rewrite" approach.
A few vendors offer dynamic flattening or hosted SPF as a paid feature: PowerDMARC, EasyDMARC, dmarcian, and Valimail are the names that appear most often in the deliverability community. [VERIFY] Product naming and packaging changes frequently in this category, so confirm exactly what each one ships before recommending. The vendor-side mechanics are similar across the category: you delegate SPF resolution to their infrastructure via an include:, they re-resolve continuously, and they update what their hosted record returns.
The sales pitch is that you stop having to think about lookup-count drift. The honest pitch is that you've added an external dependency on a third party for a record that determines whether your mail gets delivered. If their service has an outage or a regression, your SPF record stops resolving correctly until they fix it. That's not a hypothetical — it has happened more than once across the vendor category.
Dynamic flattening is the right answer when you're tired of fixing static flattening and your team can absorb the third-party-dependency risk. It's not the right answer if you're a small operator with two domains and a working static record.
The honest tradeoffs
Static flattening is free (as in beer; not as in time). It works until a sender changes their IPs. It's reversible — you can always re-flatten. The labor cost is real, ongoing, and easy to deprioritize until something breaks.
Dynamic flattening costs money and adds a dependency. It works continuously, until the vendor has an incident. The labor cost is paid in dollars instead of hours. The dependency cost is paid in incident-response complexity when something goes wrong and you're trying to triage between "our DNS," "their hosted record," and "the receiver's resolver."
There's a third option people forget: the deprecated redirect= mechanism lets you point an SPF lookup at another domain entirely. Some operators have used redirect= against their own consolidated SPF zone to centralize maintenance. It still counts as a DNS lookup, doesn't reduce your lookup budget, and most modern guidance treats it as legacy. Don't reach for it.
The single most common piece of advice from deliverability practitioners is this: most experts recommend reducing senders before flattening. If you're at 14 lookups because three of your include:s are unused, the cleanup pass gets you back to 11 lookups, which is still a permerror but a much smaller problem. Flattening dirty inputs produces clean outputs that are still wrong.
The "before you flatten" questions
Before you reach for any flattening tool — static or dynamic — answer these. If you can't say "yes" to most of them, flattening will make your record technically valid but won't fix the underlying problem.
- Have you audited your senders? Walk every
include:in your current record. For each one, can you name the business process that uses it and the person who owns it? If not, it's a candidate for removal. - Are any of your senders deprecated? The marketing platform you switched off two years ago. The ticketing tool that got merged into a different system. The transactional provider you migrated away from last quarter. These almost always still have entries in your SPF record.
- Do you have a way to be notified when senders change IPs? If you're flattening statically, this is the gating question. Microsoft and Google add netblocks without announcement. Without monitoring, your flattened record drifts out of sync silently until mail fails.
- Is your SPF over the limit because of legitimate use or accumulated cruft? If the answer is "legitimate use" and you genuinely send through 10+ services, flattening is appropriate. If the answer is "cruft," the audit is the fix and flattening is premature optimization.
- Have you tried consolidating stable senders to
ip4:/ip6:ranges? If you have an MTA on a fixed IP, or a transactional provider with dedicated IPs, replace theinclude:with explicit IP ranges. This counts as zero lookups and is more maintainable than full flattening. - Do you have a process for new senders? If marketing can sign up for a new SaaS tool tomorrow without IT being looped in, your record will drift back into permerror inside 12-18 months regardless of which path you pick.
- Are you ready to maintain this? Flattening — static or dynamic — is a commitment, not a fix. Make sure someone owns the SPF record going forward.
If you got "yes" on most of these, proceed. If you got "no" on three or more, the audit is your project, not the flattener.
The DMARCit approach
We're in the process of building hosted SPF — the v1 product surface is early-warning first-seen detection plus a monthly SPF audit, not a real-time observability stream. The technical depth is in the hosted SPF spike, and the honest summary is that DNS caching at receivers means anyone advertising real-time SPF visibility is overstating it. The signal is sparse, but it's still useful — a flattened-record drift caught the day after Microsoft adds a netblock is far better than the same drift caught two weeks later when a customer complains.
When hosted SPF ships [VERIFY: hosted SPF status — currently roadmap, see #23 spike], we'll position it the same way the rest of DMARCit's product is positioned: alignment-evidence-gated, anti-FUD, factual. The pricing floor for the SPF telemetry tier is $39/month [VERIFY: per-tier domain count at $39 Pro tier] — that's the cost reality of running a hosted SPF service with proper privacy controls and log analytics, not a competitive critique of vendors who price lower.
If you're shopping today, the honest answer is: a working static-flattening pipeline plus monthly audit beats a hosted service if you have the engineering bandwidth. Hosted services start to win when you're managing 5+ domains, when you've broken SPF more than once, or when you're trying to advance to p=reject on DMARC and SPF posture keeps blocking you. (See /learn/p-quarantine-vs-p-reject for the enforcement-readiness side of that decision.)
For the broader category landscape, see the /compare/dmarc-tools pillar page and the head-to-head pages: /compare/easydmarc, /compare/powerdmarc, /compare/dmarcian, /compare/mimecast. [VERIFY: MTA-STS hosting status, BIMI workflow status, Cloudflare DNS one-click integration status, support SLA / founder-access specifics, pricing-footnote asterisk on BIMI/MTA-STS parity — all carried from the comparison-page set; resolve before publish.]
Common flattening pitfalls
The pitfalls below are the ones we see most often when reviewing customer SPF records that have been flattened previously. None of them are exotic. All of them are recoverable, but most cost a couple of days of deliverability incident before anyone notices.
Forgetting to flatten subdomains. Your apex domain is at v=spf1 ip4:... -all, your mail.example.com subdomain still has v=spf1 include:_spf.google.com ... and is over the limit. Flattening is per-record. Audit every subdomain that publishes SPF.
Not updating after Microsoft 365 IP changes. Microsoft adjusts spf.protection.outlook.com netblocks on its own schedule. The diff is usually small but can include a netblock that handles a meaningful percentage of your outbound. If your re-flatten cadence is "manual, when I remember," you'll miss the change.
Double-counting due to overlapping includes. Two senders that both happen to use the same upstream provider can produce overlapping IP ranges in your flattened output. The result still works, but it bloats the record and makes future diffs noisier. Run a deduplication pass before publishing.
Leaving deprecated ptr mechanisms in place. The ptr mechanism is deprecated by RFC and discouraged by every modern guide; some receivers will hard-fail evaluation when they see it. If your old record had ptr in it, the flattened version should not.
Exceeding the 512-byte UDP DNS response size. Flattened records get long. RFC 7208 §3.4 reminds you that DNS responses over 512 bytes force fallback to TCP or EDNS0, and some misconfigured resolvers handle that poorly. If your flattened record runs to thousands of bytes, split it across multiple TXT strings (which DNS supports — strings are concatenated by resolvers) and confirm your authoritative DNS is set up to serve large TXT records cleanly.
Treating the flatten as final. This is the meta-pitfall. The record you publish today is correct today. It will be wrong on a schedule that depends on which senders you flattened. Build the re-flatten pipeline before you publish, not after.
What to do next
If you're staring at a permerror right now and reaching for a flattener:
- Run the seven "before you flatten" questions above. If three or more come back "no," do the audit first.
- Cut unused senders. Most readers reduce their lookup count by 30-50% in this step alone.
- Consolidate stable senders to
ip4:/ip6:ranges where possible. - If you still need to flatten, decide static vs dynamic based on whether you can maintain the pipeline.
- Set the re-check cadence before you publish. A monthly scheduled re-flatten is a reasonable floor; weekly is better if your sender mix changes often.
Check your SPF record's lookup count
See where you stand before deciding what to flatten. We watch the record, flag drift before it becomes a permerror, and run the cleanup pass with you.
/tools/dmarc-checkercoming soon — for now, see pricingTalk to the founder: book a demo contact us