SPF record checker

Expands every include: and counts your DNS lookups against the limit of 10. Cross it and SPF stops working — with no bounce, no warning, and a record that still looks correct.

Queries TXT records over DNS-over-HTTPS (Cloudflare, falling back to Google). Only the domain names being resolved are sent, to the resolver — never to us.

The 10-lookup limit, and why it breaks things quietly

RFC 7208 §4.6.4 caps an SPF evaluation at 10 DNS-querying terms. include, a, mx, ptr, exists and the redirect modifier each cost one. ip4, ip6 and all cost nothing.

The count is not just your own record — it is everything your include: terms pull in, recursively. Adding one SaaS sender can add four or five lookups you never see, because they are inside their record.

Cross the limit and the result is permerror. Receivers treat that as "SPF did not pass", so mail that authenticated perfectly well yesterday starts failing — and nothing tells you. No bounce mentions it. Your DNS is valid. The record looks exactly as it did when it worked. This is the single most common way a working SPF setup dies.

How this tool counts

It counts as if every term is evaluated, which is the worst case and also what receivers hit whenever no earlier mechanism matches. Real evaluation stops at the first match, so a passing message may use fewer — but you cannot rely on that, because a message from your last-listed sender walks the whole record.

include: and redirect= are expanded and their contents counted. a, mx, ptr and exists are counted at one lookup each without being resolved — the count is what matters, and resolving them would not change it. Terms containing macros such as %{i} cannot be expanded without a specific sending IP, so they are counted and flagged rather than followed.

What to do when you are over

  • Drop senders you no longer use. The usual cause is accumulation — a record nobody has audited since three vendors ago. This is free.
  • Replace an include with the ip4 ranges behind it, where the vendor publishes stable ones. Trades a lookup for a maintenance burden: their IPs change and yours do not follow.
  • Use a or mx instead of an include where a sender is really just your own mail host.
  • Send vendor mail from a subdomainmail.yourdomain.com with its own SPF record and its own budget of 10. This is the durable fix, and it also keeps a vendor breach off your main domain.

What does not work is publishing a second SPF record. Two records is permerror too (§4.5), so splitting one long record in half breaks SPF entirely rather than halving anything.

SPF alone does not stop spoofing

SPF authorises servers, not the address a reader sees. It checks the envelope sender, which nobody looks at, and it survives neither forwarding nor mailing lists. That is why DMARC exists: it requires the SPF-authenticated domain to align with the visible From: address, and it lets you say what should happen when nothing aligns.

Which is where this stops being a one-off check. Whether your SPF changes helped is a question only the daily aggregate reports answer, per sending source, over time. DMARC Analyzer collects and reads those for you — free and open source, and self-hosted, so the data stays yours.