SPF Lookup Counter

Count the DNS lookups your SPF record needs, and see which include costs how many. Free and open source (MIT).

npx spf-lookup-counter example.com

Why the number matters

SPF allows at most 10 DNS lookups and 2 void lookups per check (RFC 7208 §4.6.4). Go over either limit and receiving mail servers return permerror. SPF then fails for all your mail, and DMARC can no longer pass on SPF.

It usually happens without anyone changing your record: a provider you include: adds another nested include, and your total goes from 9 to 11.

What you get

$ npx spf-lookup-counter primedevforce.com
primedevforce.com
  v=spf1 include:secureserver.net -all

DNS lookups:  3 of 10 allowed
Void lookups: 0 of 2 allowed

Term                                             Lookups
include:secureserver.net                           3
  include:spf-0.secureserver.net                   2
    include:spf.protection.outlook.com             1

Options

OptionWhat it does
--jsonPrint the full result as JSON
--server <ip>Use this DNS server instead of the system one
--doh [url]Use DNS-over-HTTPS (Cloudflare by default). The names you look up are sent to that provider

Exit code 0 means no errors, 1 means errors found and 2 means it could not complete. That makes it easy to run in CI after a DNS change.

Fixing a record that is over the limit

  1. Look at the Lookups column. Start with the biggest numbers.
  2. Remove includes for services you no longer send mail through.
  3. Replace a and mx with ip4: or ip6: ranges if your own servers rarely change. IP ranges cost no lookups.
  4. Move a sending service to a subdomain with its own SPF record, if the provider supports it.

Use it as a library

import { countSpfLookups } from "spf-lookup-counter";

const r = await countSpfLookups("example.com");
console.log(r.lookups, "of", r.lookupLimit);

Full details of what is and isn't counted are in the README.