SPF record checker

Check a domain's SPF record and count its DNS lookups through every include against the limit of 10.

An SPF checker reads the TXT record on your domain that starts with v=spf1, follows every include, and counts the DNS lookups. RFC 7208 allows 10: include, a, mx, ptr, exists and redirect each cost one, and ip4, ip6 and all cost none. A record that needs more returns a permanent error, so SPF fails for every message. This checker draws the include tree with the running count.

Last verified . The sources named on this page were read that day.

SPF record checker, the tool

Sample report. kestrel-labs.example is a made-up domain

Its records are written to show each kind of finding. Check your own domain above.

Fail

SPF needs 11 DNS lookups and the limit is 10, so receivers return a permanent error and SPF fails.

Looked up kestrel-labs.example (TXT)

Record as published

v=spf1 include:_spf.google.com include:sendgrid.net include:mailgun.org include:amazonses.com a mx ~all

Include tree, with the running lookup count

kestrel-labs.exampleLookups used
  1. include:_spf.google.com1 of 10
    1. 8 address ranges, no lookups; ends in ~all
  2. include:sendgrid.net2 of 10
    1. include:ab.sendgrid.net3 of 10
      1. 4 address ranges, no lookups; ends in ~all
    2. 11 address ranges, no lookups; ends in ~all
  3. include:mailgun.org4 of 10
    1. include:_spf.mailgun.org5 of 10
      1. include:_spf1.mailgun.org6 of 10
        1. 4 address ranges, no lookups; ends in ~all
      2. include:_spf2.mailgun.org7 of 10
        1. 7 address ranges, no lookups; ends in ~all
      3. Ends in ~all
    2. include:_spf.eu.mailgun.org8 of 10
      1. 11 address ranges, no lookups; ends in ~all
    3. Ends in -all
  4. include:amazonses.com9 of 10
    1. 13 address ranges, no lookups; ends in -all
  5. a10 of 10
  6. mx11 of 10 over the limit
  7. ~all

11 of 10 lookups. Receivers stop at 10 and return a permanent error.

What each term does

v=spf1
Marks this TXT record as SPF version 1.
include:_spf.google.com
Also allow the servers in the SPF record of _spf.google.com. Costs a lookup, plus any lookups inside it.
include:sendgrid.net
Also allow the servers in the SPF record of sendgrid.net. Costs a lookup, plus any lookups inside it.
include:mailgun.org
Also allow the servers in the SPF record of mailgun.org. Costs a lookup, plus any lookups inside it.
include:amazonses.com
Also allow the servers in the SPF record of amazonses.com. Costs a lookup, plus any lookups inside it.
a
Allow the address records of kestrel-labs.example. Costs a lookup.
mx
Allow the mail servers in the MX records of kestrel-labs.example. Costs a lookup.
~all
Softfail every server not listed before it: accept, but mark as suspicious.
  • 11 DNS lookups, counted through every include. SPF allows 10.

What to do

Remove includes for services you no longer use, or move a sender onto its own subdomain with its own record. Flattening includes into IP addresses also works, but the list goes stale when a provider changes its addresses.

The rest of the report

  • DKIMWarningDKIM key found at google: 1024-bit RSA key. RFC 8301 says signers should use at least 2048 bits.
  • DMARCWarningDMARC is at p=none, which makes no request about failing mail. Once reports show all your senders pass, move to quarantine.
  • MXPass1 MX host, and it resolves. Mail is hosted by Google Workspace.
  • BIMINot foundNo BIMI record. BIMI is optional, and it needs DMARC at quarantine or reject before any inbox shows a logo.
  • MTA-STSNot foundNo MTA-STS record. It is optional; it tells senders to refuse delivery without verified TLS to your listed MX hosts.
  • BlocklistsCould not checkNot listed on the 14 queries that answered. Spamhaus DBL could not be checked from our server.

The 10-lookup limit

  1. v=spf1Version0
  2. include:_spf.google.comGoogle Workspace1 lookup
  3. include:mailgun.orgMailgun, with the includes inside it5 lookups
  4. ip4:203.0.113.0/24An address range0
  5. mxYour MX hosts1 lookup
  6. ~allEveryone else0
7 of 10 lookups used, 3 left
Sample. A made-up record. Include costs are each provider’s record as published on the date in the builder below.
Nested includes
An include costs one lookup plus every lookup inside the record it pulls in. The tree in the report shows the running total.
Void lookups
A lookup that finds nothing. Receivers should stop after 2.
One record only
Two v=spf1 records on one name are a permanent error. The checker writes the merged record.
Long records
Strings over 255 characters are split, and receivers join them without spaces. The checker flags a split that breaks a term.

Flattening, and what it costs

Flattening swaps an include for the address ranges it lists today, which cost no lookups. When the provider adds an address, mail from it fails SPF until someone updates your record. Try these first:

  • Remove includes for services you no longer use.
  • Check whether a service needs your record at all. SPF reads the envelope sender, and a service that uses its own bounce domain there is covered by its own record. SendGrid’s CNAME setup and Amazon SES’s MAIL FROM subdomain work this way.
  • Our recommendation: give a high-volume sender its own subdomain, which gets its own record and its own 10 lookups.

SPF record builder

Tick the services that send as your domain.

Services that send as your domain
Everything else
Host
yourdomain.com
Type
TXT
Value
v=spf1 include:_spf.google.com ~all
1 of 10 lookups

Lookup costs read from each provider’s SPF record on October 18, 2026; providers change them. Includes from: Google Workspace, Microsoft 365, Zoho Mail, Fastmail, Proton Mail, iCloud+ custom domain, Mailgun, SendGrid, with automated security off, Amazon SES, on a custom MAIL FROM domain. HubSpot gives each account its own value, in your HubSpot domain settings.

How the record ends

-all
Fail every server not listed. Microsoft’s example ends this way.
~all
Softfail every server not listed. Google’s value ends this way, and it is our recommendation, with DMARC doing the enforcing.
?all
Neutral, the same as no ending and no redirect.
+all
Pass every server on the internet. A bare all means the same.
HELLOmy name is{first_name}

Nobody replies to {first_name}

We write to the person: a list of companies you can defend, a research note behind each, and every email checked by a person and sent from your own domain.

A person replies within one working day. No newsletter.