Skip to content

SPF Flattening

SPF flattening resolves the include: mechanisms in your SPF record down to the raw IP ranges behind them, and replaces them with ip4:/ip6: entries — which don’t count against SPF’s 10-DNS-lookup limit. It’s the fix for one specific problem: when chained include:s push your record over that limit and SPF starts failing for all your mail. It is not something every domain needs, and it comes with a real maintenance cost. For the full background on how SPF works, see Understanding SPF.

The 10-lookup limit

Every include:, a, mx, ptr, exists, and redirect in your SPF record costs the receiving server a DNS lookup to evaluate — and many include:s contain their own nested includes, each costing more. RFC 7208 caps the total at 10. Go over, and receivers return permerror — a permanent SPF failure — for every message, regardless of where it was actually sent from. If your mail relies on SPF for its DMARC alignment, that failure can pull DMARC down with it.

That’s the trap flattening solves: each include: you replace with the literal ip4:/ip6: ranges behind it removes its lookups from the count, because IP entries are evaluated with zero DNS lookups.

Do you actually need to flatten?

Check your lookup count before you change anything. The checker counts your record’s live DNS lookups and tells you exactly where you stand:

  • 8 or fewer — you’re fine. Don’t flatten. Flattening a healthy record adds maintenance burden for no benefit.
  • 9–10 — close to the limit (the checker warns here). Worth acting before you trip it.
  • Over 10 — broken (fail: “exceeds the 10-lookup limit”). Your mail is already failing SPF.

And when you do need to act, flattening isn’t the first move. The cheapest fix is removing senders you no longer use — an old marketing platform you migrated off, a trial tool still sitting in the record. That costs nothing and never goes stale. Flatten only the sources you keep that have stable, rarely-changing IPs — ideally infrastructure you control.

Worked example: bringing a record back under the limit

Say example.com has accumulated this record over the years:

v=spf1 include:spf.protection.outlook.com include:_spf.google.com include:servers.mcsv.net include:sendgrid.net include:_spf.mailrelay.example.com include:_spf.oldesp.com include:spf.trialcrm.com -all

Resolved live, those includes — several nesting their own includes — add up past ten:

MechanismWhat it’s for~Lookups
include:spf.protection.outlook.comMicrosoft 3652
include:_spf.google.comGoogle Workspace (nests three netblocks)4
include:servers.mcsv.netMailchimp1
include:sendgrid.netSendGrid1
include:_spf.mailrelay.example.comthe company’s own mail relay3
include:_spf.oldesp.coma marketing platform they left1
include:spf.trialcrm.coma trial that ended1
Total13

That’s 13 — the checker returns fail: “13 DNS lookups — exceeds the 10-lookup limit.” Every message is permerror-ing.

Move 1 — remove what you don’t use. Two includes are dead: _spf.oldesp.com and spf.trialcrm.com. Delete both and you save 2 lookups, down to 11. Helpful — but Microsoft 365 and Google alone account for six unavoidable lookups, so clearing dead weight isn’t enough on its own here. You’re still over.

Move 2 — flatten one stable source you control. You can’t flatten Microsoft 365 or Google — they rotate their sending IPs constantly, and a static snapshot would break within weeks. But the company’s own mail relay has fixed IPs that rarely change. Resolve _spf.mailrelay.example.com to its ranges and substitute them as ip4: entries (shown here with RFC 5737 documentation ranges):

v=spf1 include:spf.protection.outlook.com include:_spf.google.com include:servers.mcsv.net include:sendgrid.net ip4:192.0.2.0/24 ip4:198.51.100.0/24 -all

Those ip4: entries cost zero lookups, replacing the relay’s three. The total drops to 8 — the checker now returns pass: “8 of 10 allowed DNS lookups used.” The -all terminator is preserved throughout (the checker reads it as the strongest SPF posture); flattening changes how sources are listed, never how strict the record is.

Check your own record

The checker counts your live DNS lookups, reads your all terminator, and tells you whether you’re under, near, or over the limit — and which mechanisms cost the most. If you do need to flatten, it builds the rewritten ip4:/ip6: record for you to publish. Start there to see where you stand: