How SPF Guru works
SPF Guru does not shorten your record. It puts two macro-based includes at the front of it, and answers those two queries by evaluating the rest of the record on your behalf, where the ten-lookup limit does not apply.
The problem: ten DNS lookups
SPF lets a domain owner declare which servers may send on its behalf, with a
hard limit of ten DNS-resolving terms. Each include:,
a, mx, ptr, exists and
redirect= counts against it.
Exceed the limit and evaluation returns permerror. Receiving
servers treat that as no usable SPF result, DMARC alignment fails on the SPF
side, and mail that should have been authenticated is not.
Why it happens so often
A typical organisation sends from several platforms: Microsoft 365, Google
Workspace, a CRM, a helpdesk, a marketing tool. Each contributes an
include:, and those includes contain includes of their own. Four
or five vendors is usually enough to go over.
Best practice first: use subdomains
The cleanest long-term fix is to send different classes of mail from different subdomains, each with its own short record:
mail.example.comfor corporate mailmarketing.example.comfor campaign platformsalerts.example.comfor transactional mail
If you can do that, do it. SPF Guru exists for the cases where you cannot, because a vendor insists on your root domain or a system is too old to change.
What SPF Guru adds to your record
One exists term, and your own policy moved up behind it:
v=spf1 exists:i.%{ir}._d.%{d}.my.spf.guru ~all <your existing mechanisms>
The include uses SPF macros. %{ir} expands to the connecting IP
address in reverse order, and %{d} to your domain. For 1.2.3.4
sending as example.com, a receiving server resolves exactly one name:
i.4.3.2.1._d.example.com.my.spf.guru
The all keeps whatever qualifier your record already had. If you
published -all you still hard fail, and ?all is still
neutral. We are reducing lookups, not changing your policy.
What happens when that query arrives
- SPF Guru reads the IP and the domain out of the query name,
fetches your published record, and evaluates the mechanisms that sit after
the
all. - If that IP is authorised, it answers. An
existsmechanism matches when the name resolves, so your record matches there and evaluation stops with a pass. One lookup. - If it is not authorised, there is no answer, the mechanism
does not match, and the very next term is your own
all, which decides the outcome. Still one lookup.
Each unauthorised check spends one of the two void lookups RFC 7208 allows, because an empty answer is how the mechanism says no. That is the one cost this design carries, and it leaves a margin of one.
Do not delete the rest of your record. The mechanisms
after the all are not leftovers. Receivers ignore them, which is
the point, but they are the input SPF Guru reads when answering. Remove them
and there is nothing to evaluate, so every sender fails. To roll back, delete
the guru include and move the all back to the end.
If SPF Guru is unreachable
This is the reason the record uses exists rather than
include. An include pointing at a name that does not
resolve is a permerror under RFC 7208, which would break the record
for every sender the moment our DNS had a bad day. An exists that
cannot be answered is simply "no match", so evaluation moves to the next term
and your own all still decides.
Unauthorised mail is therefore still handled exactly as you intended. What you lose during an outage is recognition of your authorised senders, so they soft-fail rather than pass, and DKIM carries DMARC until the lookup works again.
You can protect one sender against even that by putting its include directly
after the guru term, before the all:
v=spf1 exists:i.%{ir}._d.%{d}.my.spf.guru include:spf.protection.outlook.com ~all <the rest>
Because a non-matching exists falls through, that include is
reached whenever SPF Guru does not answer, and skipped entirely whenever it
does. Unlike the older design there is no ordering trap and no cost in the
normal case.
Choose the vendor for cost anyway, since it is paid on every check that SPF
Guru does not match. Microsoft's spf.protection.outlook.com is a
flat list of addresses and costs one lookup. Google's
_spf.google.com nests three more records behind it and costs four.
This protects only the senders you list.
Already publishing the include form?
Earlier records used include:i.%{ir}._d.%{d}.my.spf.guru instead
of an exists, and those keep working. SPF Guru still answers them,
they still cost one lookup, and this site still recognises a domain using one as
already configured. Nothing breaks and there is no deadline.
The difference only shows up when SPF Guru cannot answer. An
include pointing at a name that does not resolve is a
permerror, so an outage would break the record for every sender,
where the exists form falls through to your own all.
That is why the tool now generates exists, and it is the only
reason to switch.
Why this is not flattening
SPF flattening tools expand your vendors into a literal list of IP addresses. That list is correct on the day it is generated and starts rotting immediately, because vendors add and renumber servers without telling you. SPF Guru resolves your record at query time, so adding a vendor to it works straight away with no regeneration step.
What other checkers will tell you
Your record still contains all its original mechanisms, so a checker that counts terms without evaluating them will still report more than ten lookups. That is expected. The number that affects delivery is the number a receiving server actually performs, which is two.
Trade-offs worth knowing
- Your SPF result depends on SPF Guru's DNS being reachable. If it is not,
evaluation returns
temperrorrather than falling through to the rest of your record. - This is a free, best-effort service. Configure DKIM as well, so DMARC has a second way to pass. See the disclaimer.
SPF Guru does not replace best practice. It buys you deliverability where best practice cannot be applied.