SPF lookup counter

RFC 7208 caps an SPF evaluation at ten DNS lookups. Over the cap it is a permerror, and most receivers treat a permerror as no SPF at all. This walks the whole include tree and shows you exactly where the count goes.

Try: box.com hubspot.com salesforce.com rastu.tech

What counts against the ten

MechanismCostNotes
include:1 + its own Recursive. An include that itself has four includes costs you five.
redirect=1 + its own Same as include, and it replaces the rest of the record.
a a:1 Including the CIDR forms, a/24 and a:host/24.
mx mx:1 And capped separately at ten address records per evaluation.
exists:1 Often carries a macro, so the cost can depend on the sending IP.
ptr1 Deprecated by RFC 7208. Some receivers ignore it. Remove it.
ip4: ip6:0 No DNS query, so unlimited.
all exp=0 exp= is only fetched on a fail, and never counts.

Every mechanism can carry a qualifier, so +include:, -a and ~mx cost exactly what the unqualified form costs. Tools that match on the bare token miss them and report a broken record as healthy.

Why this is worth checking

It is the failure nobody sees coming. The record resolves. It reads correctly. It passes a visual inspection. It has simply stopped authenticating, usually because somebody added one more vendor to a record that was already at nine. Across 100,000 domains, 3.4% of every published SPF record had already crossed the line.

On flattening

Flattening means replacing an include: with the IP ranges it currently resolves to. It fixes the count today and creates a slower problem: when the provider adds a sending range, your record does not know, and mail from the new range fails SPF with no error anywhere to tell you. If you flatten, you own a record that has to be re-generated on a schedule, and somebody has to still be doing that in a year.

Cheaper answers first: remove vendors that no longer send, move mail to a subdomain with its own record, and collapse two ESPs into one.