SPF flattening by DomainWarn
An SPF record may cause at most ten DNS lookups when it is evaluated (RFC 7208). Every include, a, mx and redirect counts, including the includes of the services it pulls in: Google Workspace, Microsoft 365, a newsletter tool and a ticket system quickly go beyond that. Receivers then treat the record as an error (PermError) – and mail that should pass fails SPF.
DomainWarn flattens the record: it resolves every include, a, mx and redirect recursively into the networks they allow, removes duplicates, merges adjacent networks and publishes the result as _spf.client.example. If it does not fit into one record (at most 450 characters, so the answer still arrives whole over UDP), DomainWarn splits it into _spf.client.example, _spf1.client.example, _spf2.client.example …, each part including the next. The domain's SPF record then becomes v=spf1 include:_spf.client.example -all – with the all of the original – and needs one lookup per part instead of twelve or fifteen.
In the "Email" tab of a domain, open "SPF flattening". Even before switching it on, the card shows the result: lookups before and after, the records and the domain's new SPF record. "Flattened by DomainWarn" under "Manage" switches it on (from the Freelancer plan). The source is the SPF record currently at the domain; after the switch you add new services in the card under "Source". If the client changes the record at the domain again themselves (without the include), DomainWarn takes it as the new source.
_spf.client.example. TXT "v=spf1 ip4:35.190.247.0/24 ip4:40.92.0.0/15 ip4:40.107.0.0/16 ip6:2001:4860:4000::/36"
client.example. TXT "v=spf1 include:_spf.client.example -all"One click instead of typing: if the zone is connected through an integration (Cloudflare, Hetzner DNS, IONOS, netcup, INWX or Route 53), "Set up with Cloudflare" (or the respective provider) first creates the parts at _spf and then replaces the domain's SPF record. DomainWarn only replaces the existing SPF record after explicit confirmation; other TXT records at the domain (such as verifications) stay untouched. If a part fails, the old SPF record stays in place – otherwise the new one would point nowhere.
Services change their networks now and then. DomainWarn therefore resolves the record again daily and after every SPF check; every change shows in the card's history and as "Flattened SPF record updated" with the added and removed networks in the timeline. With "Update the DNS record automatically on changes" DomainWarn rewrites the parts at _spf itself (including a new part when more networks come in) – the automatic update never touches the domain's SPF record. Without an integration DomainWarn reports "Flattened SPF record outdated" with the new content to copy once the include is at the domain and the parts no longer match. "Resolve now" under "Manage" triggers this immediately.
Not everything can be flattened. Macros (%{i}, %{d} …), exists and ptr depend on the individual sender and cannot be expressed as fixed networks; a mechanism with a qualifier other than + before the all would lose its order. The card then names the part, and the feature cannot be switched on. On top of that come limits against runaway records: at most ten DNS mechanisms per level, five levels deep, 64 networks after merging. Networks larger than /16 (IPv4) or /32 (IPv6) are taken over but listed as a notice – usually a typo or a very generous service is behind them.
Switching off only works once the domain has its own SPF record again: if it still includes _spf.client.example, the networks would otherwise stay frozen. DomainWarn leaves the records at _spf in place when switched off. The SPF check keeps checking from the outside how many lookups the record really causes.
See also: Check an SPF record · What is checked