The 10-DNS-lookup limit in SPF (and how to stay under)
Your DMARC report inbox shows mail from your own domain failing SPF. You check the SPF record — it's there, looks fine. The MX lookup works. SendGrid shows green. But Gmail marks the message as "permerror".
You've blown through the 10-DNS-lookup ceiling. RFC 7208 §4.6.4 caps SPF at 10 DNS
queries during evaluation. Crossing it isn't a soft warning — receivers MUST treat the
result as permerror, equivalent to "no SPF record at all" for DMARC purposes.
Your alignment fails. Your mail spam-folders. Welcome to the most common SPF bug.
What counts as a lookup
Every include:, a, mx, ptr and
exists mechanism in your SPF chain triggers one DNS query. Nested
include: chains compound — Microsoft's spf.protection.outlook.com
alone fans out to 6 includes. Add SendGrid (3) + Mailgun (2) + your own A record (1)
and you're at 12 before counting your mx mechanism.
| Mechanism | Lookups |
|---|---|
ip4: / ip6: | 0 (direct match) |
a / a:hostname | 1 |
mx / mx:hostname | 1 + N (where N = number of MX records) |
include:domain | 1 + cost of nested SPF |
exists:domain | 1 |
ptr | 1 (deprecated, never use) |
redirect=domain | 1 + cost of redirected SPF |
Counting your own
UnveilScan's dmarc_alignment checker does this recursively (depth 5). You can also do it manually:
$ dig +short TXT example.com | grep spf
"v=spf1 mx include:_spf.google.com include:sendgrid.net include:mailgun.org include:_spf.salesforce.com -all"
# Each include: triggers a follow-up TXT query. Recurse:
$ dig +short TXT _spf.google.com
# returns another SPF with its own includes...
Free public tools that count for you: https://mxtoolbox.com/spf.aspx, https://dmarcian.com/spf-survey/.
Common culprits, ranked
- Microsoft 365 / Outlook —
include:spf.protection.outlook.com= 6 lookups by itself. - Salesforce —
include:_spf.salesforce.com= 4 lookups (and growing as they add IPs). - HubSpot —
include:151140.spf09.hubspotemail.net= 3. - SendGrid —
include:sendgrid.net= 3. - Marketo, Mailchimp, Constant Contact — 2-3 each.
Combining 3-4 of these guarantees you cross the limit.
How to fix
Strategy 1: prune unused vendors
Most domains have legacy include: entries from vendors they stopped using
years ago. Audit. If you don't use Mailchimp anymore, remove its include. Each removal
frees 2-3 lookups.
Strategy 2: replace include with explicit ip4
Vendors publish their IPs (or subnets). For static-IP services, you can flatten:
# Before (1 lookup)
include:_spf.google.com
# After (0 lookups — but you must keep this in sync)
ip4:35.190.247.0/24 ip4:64.233.160.0/19 ip4:66.102.0.0/20 ...
Trade-off: the vendor will rotate IPs eventually. You'll silently break sending until you update. Useful only for vendors that publish stable ranges (Google, Microsoft) and only when you're truly stuck under the 10-lookup ceiling.
Strategy 3: SPF flatteners
Services like autospf.com or spfm.com resolve every
include: chain at scheduled intervals and serve a flat ip4:
SPF record from their domain. You point a single include: at theirs. They
handle the IP rotation.
Trade-off: you're trusting a third party with your authentication record. If they're compromised, attackers add their IPs to your "authorised" list. Use only providers with a long track record + strong audit.
Strategy 4: split mail traffic across subdomains
Each subdomain has its own SPF, with its own 10-lookup budget. Marketing emails
from marketing.example.com with HubSpot only. Transactional from
tx.example.com with SendGrid only. Support from support.example.com
with Zendesk only. The apex stays clean.
Best long-term solution. Costs nothing, no third-party dependency. Requires you to actually configure each vendor with the right subdomain.
What we recommend
Audit first (Strategy 1). Most domains hit 12-13 because of legacy includes; pruning drops them to 7-8. If after pruning you're still over, split traffic by subdomain (Strategy 4). Use flatteners (3) only as a temporary fix for an apex that genuinely needs 6+ vendors.
-all (hard fail), not ~all
(soft fail). DMARC enforcement only works if SPF says "no" with conviction.
