SPF Flattener Tool
Introducing My SPF Flattener
Lately I’ve been scratching a very specific itch: SPF records. These tiny TXT records live in your DNS and tell receiving mail servers who is authorised to send email on behalf of your domain. When they work, you never notice them. When they don’t, your mail gets quietly thrown into the spam abyss. It turns out there are two gotchas baked right into the SPF specification: you only get ten DNS lookups and each string is limited to 255 bytes. If you use a handful of SaaS platforms to send email, you’ll hit those limits surprisingly quickly.
Why flatten your SPF record?
Every time your SPF record contains an include: statement (e.g. include:_spf.google.com) the receiving server has to do another DNS lookup. That lookup counts toward the ten-lookup cap. Once you exceed the limit, the mail server stops evaluating your record and your mail fails SPF. A common workaround is flattening: you resolve each include: into its underlying IP ranges and replace the include with those IP ranges directly. Because literal IPs don’t require lookups, your record stays under the limit.
Flattening is not without its downsides. IP ranges change, so you need to monitor and regenerate the record periodically. The flattened record also grows longer, which brings us to the second gotcha: a single text string in a DNS TXT record can’t exceed 255 bytes. Once your flattened record gets too long, you either split it into multiple quoted strings or move authorisations to sub-domains (e.g. _spf1.example.com, _spf2.example.com) and include: those. This is where tools can help.
Building my own SPF flattener
There are plenty of services out there that will flatten your SPF record, but I wanted something simple, transparent and self-hosted. So I built a tool that does just two things:
- Takes your domain and resolves every
include:. It walks down the chain of nested includes, collects all theip4:andip6:mechanisms, deduplicates them and assembles a single flat SPF string. - Splits large records into sub-SPF records. If the flattened record would exceed 255 characters, the tool automatically creates
_spf1,_spf2, etc., publishes the fragments in separate TXT records and writes an include list for your apex domain. No more manual counting or hand-crafting quoted chunks.
The tool runs as a simple web page. You enter your domain, hit “Flatten” and it returns a JSON payload with the flat SPF string and any sub-records. To make it approachable I added a short explainer at the top about what SPF is and why you might need to flatten or split records. If you’re curious, it’s all hosted at spf.bgall.uk.
A quick example
Suppose your original SPF record looks like this:
v=spf1 include:_spf.google.com include:spf.protection.outlook.com ~all
That record requires two DNS lookups. If either of those providers nests further includes, you quickly bump into the ten-lookup ceiling. Flattening converts it to something like this (IP ranges shortened for clarity):
v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.0/24 ip4:203.0.113.0/24 ~all
Now there are no lookups left to count; all of the authorised servers are explicitly listed. If the resulting string were longer than 255 characters, the tool would instead create _spf1.example.com and _spf2.example.com containing chunks of the record and include them in the apex record.
Use it, but be careful
Flattening is a neat workaround, but remember that IP ranges change. Flattening trades readability and ease of maintenance for compliance and can create a bigger attack surface if you’re not careful. My tool doesn’t solve that problem-it just automates the tedious part. You still need to review your authorised senders periodically and regenerate your record when providers update their IPs.
That said, if you have a messy SPF record and want to see what a flattened version looks like, give spf.bgall.uk a try. It’s self-hosted by me and free to use. I built it to scratch my own itch; maybe it will scratch yours too. Let me know what you think!