SPF record check
Walks your entire include chain, counts the DNS lookups exactly as a receiving server does, and tells you what to fix. Most checkers stop at the first record.
Judged against RFC 7208
Symptoms
SPF fails quietly. Nothing in your mail client changes, no bounce arrives, and the record still looks fine when you read it. What you notice instead is that mail to some recipients starts landing in spam, a vendor's newsletters stop arriving, or DMARC reports show failures for mail you definitely sent.
The usual causes, in the order we find them:
- The record grew past ten DNS lookups when somebody signed up for one more tool.
- Two SPF records exist because a provider added one without removing the old.
- The record ends in
?allor has noallat all, so nothing is ever refused. - An old vendor's
include:now points at a domain that no longer publishes SPF.
Diagnosis
SPF is a list of who may send mail using your domain on the envelope. A receiving server reads your record, follows every include: it contains, and builds the full set of authorised addresses. That expansion is the expensive part, and the specification caps it.
The ten-lookup limit
Ten DNS-lookup-consuming terms, total, across the whole chain, include, a, mx, ptr, exists andredirect=. ip4: and ip6: are free, which is why flattening works. Exceed the limit and the result is a permanent error: not "fail", not "unknown", but a record receivers stop trusting entirely.
Void lookups
A lookup that returns nothing counts too, and you are allowed only two. Three dead vendor includes will break a record that is otherwise well inside the ten-lookup budget, this is the check almost nothing else performs.
The closing mechanism
The last mechanism decides what happens to everyone not on the list. -all says refuse, ~all says treat as suspicious, ?all and +all say nothing at all, and +all authorises the entire internet to send as you.
Cure
Depending on what the test found:
- Over ten lookups, remove services you no longer use first, since that is free. Then replace a stable vendor's
include:with theip4:ranges it resolves to, and re-check whenever that vendor changes infrastructure. - Two records, merge every mechanism into one
v=spf1record and delete the rest. - No enforcing rule, end the record with
~all, then-allonce your reports are clean. - Dead includes. Remove them. They cost a lookup and a void lookup, and buy nothing.
A healthy record for a domain sending through one provider looks like this, and rarely needs to be more complicated: v=spf1 include:_spf.yourprovider.com -all
Questions people actually ask
How many DNS lookups is my SPF record allowed?
Ten. Every include:, a, mx, ptr, exists and redirect= counts, and the count is cumulative across everything those records pull in. At eleven, receivers return a permanent error and SPF fails for all of your mail, including mail from your own servers.
What does an SPF PermError actually do to my email?
It makes SPF authentication fail rather than simply not pass. Mail that would otherwise have been accepted starts landing in spam, and if you rely on SPF for DMARC alignment, DMARC fails too.
Is ~all or -all better?
Both are real answers; ?all and +all are not. Use ~all while you are still confirming which services send your mail, then move to -all once your DMARC reports show only senders you recognise.
Can I have two SPF records?
No. More than one v=spf1 record at the same domain is a permanent error and SPF fails completely. Merge them into a single record.
Does SPF stop someone spoofing my domain?
On its own, no. SPF authenticates the envelope sender, not the From address a recipient sees. DMARC is what turns SPF and DKIM into protection against spoofing.
Related tests
Every fix on this site is yours to implement. If you would rather someone did it, I take this work directly.