Your SPF record gets ten lookups. See where they go.

Every include: in your SPF record pulls in someone else's record, and theirs pull in more. Receivers may make ten DNS queries evaluating the whole tree; on the eleventh they give up with permerror, and most then treat your mail as unauthenticated. Nobody sees it happen because the break is inside a vendor's include, not yours. Type a domain and we draw the tree with a running count beside every term.

Try salesforce.com, microsoft.com, shopify.com.

How the count works

  • Ten is the limit. RFC 7208 §4.6.4: include:, redirect=, a, mx, ptr and exists: each cost one DNS lookup, and a receiver must stop at ten. ip4:, ip6:, all and exp= are free.
  • Includes nest. An include costs one lookup itself plus everything inside the record it points at. A single vendor include can quietly spend four or five of your ten, and vendors change their records without telling you.
  • The count is the worst case. Receivers walk the record left to right and stop at the first match. A spoofer matches nothing, so for exactly the mail you want rejected the whole tree is walked. If the walk crosses ten, the answer is permerror, not fail, and DMARC counts SPF as failed.
  • Void lookups. A term whose lookup returns nothing (no such name, no record) counts as void; more than two is also a permerror.
  • Missing records. An include of a domain with no SPF record is a permerror on its own, however few lookups you use.

If you are over

Drop includes for services you no longer send from. Replace a and mx with the literal ip4: ranges when they are stable. Move bulk senders to their own subdomain with its own record. Or flatten: publish the IP ranges directly and re-check them on a schedule, since a vendor's ranges will change. Our SPF checker validates the record's syntax and the email authentication report shows SPF, DKIM and DMARC together.