SPF is capped at 10 DNS-querying mechanisms (RFC 7208). Exceed it and SPF returns PermError — receivers treat it as a fail, and DMARC fails with it. This is one of the most common silent deliverability bugs.
What counts toward the limit
Each of these is one lookup, and include: recurses into the target’s record (which has its
own lookups):
include:·a·mx·ptr·exists:·redirect=
ip4: and ip6: do not count. Three or four ESP include: entries (each pulling in
several nested includes) blows past 10 fast.
Count yours
Our checker does a real recursive count of your SPF lookups and warns before and after the limit — no guessing.
How to fix it
- Remove unused includes. Old ESPs you no longer send from are the usual culprit.
- Drop
ptrentirely — it’s deprecated and wasteful. - Flatten heavy includes: replace an
include:with the actualip4:/ip6:ranges it resolves to. (Trade-off: you must update them if the provider changes IPs.) - Delegate by subdomain: send different streams from subdomains, each with its own leaner SPF record.
Verify
Re-run the checker until the lookup count is comfortably under 10, then confirm DMARC passes. Decode the final record with the explainer.