How to use it
- Type the domain your mail is sent from in Domain name and press Check.
- Read the verdict and the line under it, which says what happens to Mail from servers not listed:
- Check DNS lookups (the limit is 10) and Lookups that found nothing (the limit is 2).
- Open Includes, followed to see which include pulls in the most lookups.
- No record yet? Use Copy record on the suggested starting record, add your other sending services, then publish it as a TXT record.
How the lookup count works
RFC 7208 (section 4.6.4) lets a receiver make at most 10 DNS-querying steps while evaluating SPF. Above that the result is permerror, a permanent error, and SPF fails for every message. Lookups inside includes count too: an include whose record holds three more includes costs four, as Microsoft's SPF guide puts it. The checker walks the whole tree the same way and warns from 8.
| Term | Counts? | Note |
|---|---|---|
include: | Yes | Plus everything inside the included record |
a, mx | Yes | Replace with ip4:/ip6: if the addresses are fixed |
exists: | Yes | Rare |
ptr | Yes | RFC 7208: SHOULD NOT be published; flagged as a warning |
redirect= | Yes | Ignored when the record has an all |
ip4:, ip6:, all | No | Free |
Void lookups
A void lookup is a query that finds nothing: the name doesn't exist, or exists without a record. RFC 7208 recommends a limit of two; more gives permerror. The checker counts include and redirect targets that don't exist or hold no SPF record. An include that points to nothing is an error on its own too: per RFC 7208 it returns permerror. The usual cause is a leftover include of a service you stopped using.
~all, -all and the other endings
| Ending | SPF result | What the checker shows |
|---|---|---|
-all | fail | rejected (-all) |
~all | softfail | accepted but marked suspicious (~all) |
?all | neutral | no opinion (?all), a warning |
+all | pass | anyone can send as you, a problem |
Terms after all are never read, and without any all or redirect= the default result is neutral.
Fixing the common errors
- Two SPF records: RFC 7208 says that is a permerror. Merge them into one:
v=spf1 ip4:192.0.2.10 include:_spf.google.com include:spf.protection.outlook.com ~all. - Over 10 lookups: remove includes of services you no longer use, or move a newsletter tool to a subdomain such as
news.example.com, which has its own record and its own budget of 10. - Typos:
include=instead ofinclude:, a space after the colon, or a trailing dot all break the record (examples from Microsoft's guide).
What SPF covers
SPF checks the sending server's IP address against the envelope sender (MAIL FROM), not the From address people see. DMARC ties the two together. For domains sending more than 5,000 messages a day, Outlook.com requires SPF to pass. In the Whole email setup grade, a missing record costs 25 points, each SPF problem 15 and each warning 5.
Questions
- Do lookups inside my includes count towards the limit of 10?
- Yes. Receivers count every DNS-querying term they evaluate, including those inside included records. Having fewer than 10 includes doesn't guarantee fewer than 10 lookups.
- Should I use ~all or -all?
- Google recommends
~all. Microsoft recommends-allonce DKIM and DMARC are set up: DMARC counts both as SPF failures, but for messages without a DKIM signature it effectively ignores a~allfailure. Start with~allwhile you're still finding every service that sends for you. - Can I replace includes with IP addresses to save lookups?
- Only for senders whose addresses you control or that publish a stable list. Microsoft advises against it for Microsoft 365 because its sending addresses change often, and a copied list goes stale.
- Does a domain that sends no email need SPF?
- Yes:
v=spf1 -allsays no server may send for it, which stops spoofed mail from passing SPF. Pair it with a null MX, explained in the /mx-lookup. - Why does my subdomain show no SPF record?
- Each domain and subdomain that sends mail needs its own SPF record; the parent's record doesn't cover it.