Published April 26, 2026 ยท 13 min read
Enter your domain to see your SPF DNS lookup count and get specific recommendations for flattening.
Free SPF Check โIf your SPF record returns a permerror result โ or you've received bounce messages mentioning "too many DNS lookups" โ you've hit the SPF 10 DNS lookup limit. This is one of the most common and impactful SPF configuration errors, and it directly harms your email deliverability.
This guide explains why the lookup limit exists, how to count your current lookups, the exact process of SPF flattening, and how to maintain a flattened record over time.
RFC 7208 (the SPF specification) states that SPF evaluation must not exceed 10 DNS lookups. Each time SPF processing encounters an include, redirect, a, or mx mechanism, it triggers a new DNS lookup. If the total exceeds 10, the result is permerror โ a permanent failure.
Here's what counts as a DNS lookup:
include: โ Each include triggers at least one lookup (and potentially more if the target includes other domains)redirect= โ One lookup, plus any lookups in the redirected recorda or a:domain โ One lookup (resolves A/AAAA records)mx or mx:domain โ One lookup, plus one per MX record foundexists: โ One lookupWhat does not count as a lookup:
ip4: โ Direct IP match (no DNS needed)ip6: โ Direct IP match (no DNS needed)all โ Catch-all (no DNS needed)include:_spf.google.com, and Google's SPF record includes other domains, all of those nested lookups count toward your 10.
The fastest way to check your SPF lookup count:
curl https://korpo.pro/api/v1/check/yourdomain.com
The response includes your SPF evaluation details, including the exact DNS lookup count and which mechanisms are triggering lookups.
Start by retrieving your SPF record:
dig TXT yourdomain.com | grep spf
Then trace each include: recursively. For example, if your SPF record is:
v=spf1 include:_spf.google.com include:mailgun.org include:salesforce.com ~all
You'd count:
yourdomain.com โ the initial SPF lookup (1)_spf.google.com โ resolves to include:_spf.google.com ~all (1)mailgun.org โ resolves to include:messaging.google.com + ip4 ranges (1-3)messaging.google.com โ nested include from mailgun (1)salesforce.com โ resolves to multiple includes (2-4)That's already 7-10 lookups from just three include directives. Add your own a or mx mechanisms and you're over the limit.
# Check your domain's full SPF evaluation curl https://korpo.pro/api/v1/check/yourdomain.com # The response includes: # - spf.dns_lookups: exact count # - spf.lookup_details: which mechanisms trigger lookups # - spf.evaluation_result: pass/neutral/permerror
When SPF evaluation hits the 10-lookup limit:
permerror โ The receiver's mail server cannot definitively determine if the sending IP is authorized.p=quarantine or p=reject, your email gets spam-foldered or bounced.permerror SPF records see 15-30% lower inbox placement rates. With a strict DMARC policy, the impact jumps to 40-60% of emails being rejected or quarantined.
SPF flattening (also called SPF record compression) is the process of resolving all include: directives to their final IP addresses, then replacing those includes with direct ip4: and ip6: entries. This eliminates nested DNS lookups.
v=spf1 include:_spf.google.com include:mailgun.org include:salesforce.com include:sendgrid.net a mx ~all
v=spf1 ip4:35.190.247.0/24 ip4:35.191.0.0/24 ip4:209.85.128.0/17
ip4:198.51.100.0/24 ip4:13.111.0.0/24 ip4:204.93.64.0/24
ip4:3.91.0.0/16 ip4:13.58.0.0/16 ip6:2607:f8b0::/32 ~all
The flattened record uses zero include: directives, so it triggers zero additional DNS lookups. The receiving mail server checks each IP directly โ no recursion needed.
Document every service that sends email on behalf of your domain:
# Common ESP includes and their typical lookup counts: include:_spf.google.com โ 1 lookup include:mailgun.org โ 2-3 lookups include:sendgrid.net โ 2-3 lookups include:salesforce.com โ 3-4 lookups include:hubspot.com โ 2-4 lookups include:mailchimpapp.net โ 2-3 lookups include:zapier.com โ 1-2 lookups
For each include: directive, resolve to the final IP ranges. You can do this manually with dig:
# Resolve Google's SPF IPs dig TXT _spf.google.com # For deeply nested includes, you may need to follow chains dig TXT _spf.google.com # โ might return include:_netblocks.google.com dig TXT _netblocks.google.com # โ returns ip4 ranges
Or use our API to automatically resolve all include chains:
curl https://korpo.pro/api/v1/check/yourdomain.com
Replace all include: directives with their resolved ip4: and ip6: entries:
# Before (8+ lookups):
v=spf1 include:_spf.google.com include:mailgun.org include:salesforce.com a mx ~all
# After flattening (0 lookups from includes):
v=spf1 ip4:35.190.247.0/24 ip4:35.191.0.0/24 ip4:209.85.128.0/17
ip4:198.51.100.0/24 ip4:13.111.0.0/24 ip4:204.93.64.0/24
ip4:3.91.0.0/16 ip6:2607:f8b0::/32 ip6:2607:f8b0:4000::/36 ~all
SPF records are stored as DNS TXT records, which have a 255-byte maximum length. A flattened record with many IP ranges can exceed this limit.
Solutions:
Split your flattened record across subdomains:
# Main record (uses includes but only to your own subdomains โ 2 lookups) yourdomain.com TXT "v=spf1 include:spf1.yourdomain.com include:spf2.yourdomain.com ~all" # Subdomain 1 (no further lookups โ just IPs) spf1.yourdomain.com TXT "v=spf1 ip4:35.190.247.0/24 ip4:35.191.0.0/24 ip4:209.85.128.0/17 ip4:198.51.100.0/24 ~all" # Subdomain 2 (no further lookups โ just IPs) spf2.yourdomain.com TXT "v=spf1 ip4:13.111.0.0/24 ip4:204.93.64.0/24 ip4:3.91.0.0/16 ip6:2607:f8b0::/32 ~all"
This uses exactly 3 lookups (your main record + 2 subdomains) instead of 8+. Well within the 10-lookup limit.
If you're only using 1-2 ESPs but have 5+ include: directives from legacy services, remove the ones you're not actually using:
# Before โ everything including the kitchen sink v=spf1 include:_spf.google.com include:mailgun.org include:salesforce.com include:sendgrid.net include:hubspot.com a mx ~all # After โ only actively used services v=spf1 include:_spf.google.com include:mailgun.org ~all
If possible, reduce the number of distinct email services your organization uses. Sending from 3 platforms instead of 6 dramatically reduces SPF complexity.
After publishing your flattened SPF record, validate it:
# Check with our tool curl https://korpo.pro/api/v1/check/yourdomain.com # Or manually verify with dig dig TXT yourdomain.com # Send a test email and check the Authentication-Results header # Look for: spf=pass (or spf=permerror if still broken)
SPF flattening has one significant drawback: ESPs change their IP ranges. When Google adds a new IP block to their sending infrastructure, your flattened record with hardcoded Google IPs won't include it โ and SPF will start failing for emails sent through Google's new IPs.
| Service | Change Frequency | Risk Level |
|---|---|---|
| Google Workspace | Low (few times/year) | ๐ข Low |
| Microsoft 365 | Low | ๐ข Low |
| SendGrid | Medium (updates quarterly) | ๐ก Medium |
| Mailgun | Medium (updates quarterly) | ๐ก Medium |
| Salesforce | High (frequent updates) | ๐ด High |
| HubSpot | Medium | ๐ก Medium |
Set up a weekly or monthly cron job to re-resolve your includes and compare the resulting IPs against your current flattened record:
#!/bin/bash # Weekly SPF re-flatten check # If IPs change, alert the team to update DNS DOMAIN="yourdomain.com" CURRENT=$(curl -s https://korpo.pro/api/v1/check/$DOMAIN | jq '.spf') echo "SPF check for $DOMAIN:" > /tmp/spf-alert.txt echo "$CURRENT" >> /tmp/spf-alert.txt
Keep include: for stable services (Google Workspace, Microsoft 365) but flatten unstable or high-lookup-count services:
# Hybrid: include for stable, ip4 for variable v=spf1 include:_spf.google.com ip4:198.51.100.0/24 ip4:13.111.0.0/24 ~all
This keeps your lookup count low while minimizing maintenance for the services most likely to change IPs.
Services like EasySPF, SPFManager, and Valimail provide dynamic SPF flattening โ they host a subdomain with your flattened record and automatically update it when ESPs change their IPs. This eliminates manual maintenance entirely.
SPF's 10-lookup limit interacts critically with DMARC:
| SPF Result | DMARC Alignment | Email Outcome (p=reject) |
|---|---|---|
| pass | Aligned โ | โ Delivered |
| permerror (too many lookups) | Not evaluated โ | โ Rejected |
| softfail (~all) | Depends on DKIM | โ ๏ธ May deliver if DKIM aligns |
| neutral (? all) | Depends on DKIM | โ ๏ธ May deliver if DKIM aligns |
When SPF fails with permerror, SPF alignment is unavailable for DMARC. Your email still passes DMARC if DKIM aligns โ but if DKIM is also misconfigured, DMARC fails entirely. This is why DKIM setup and SPF record management are both essential.
If you add the flattened IPs but leave the original include: directives, you've doubled your lookup count. Remove includes when you replace them with IP ranges.
Your flattened record becomes stale when ESPs update their IP ranges. Set a calendar reminder to re-check monthly, or use automated monitoring.
A flattened record with many IP ranges can exceed the DNS TXT record limit. Use subdomain splitting (Option A above) or consolidate your sending services.
After flattening, you know exactly which IPs are authorized. Use -all (hard fail) for better protection. ~all (soft fail) gives receivers ambiguous guidance.
If you flatten only ip4: ranges but your ESP sends over IPv6, SPF will fail for those messages. Always include ip6: ranges. Check your DKIM and SPF setup with our free domain checker.
include: targets to IP addressesinclude: with ip4:/ip6: entries~all to -all if all IPs are explicitly listedip6:), not just IPv4RFC 7208 limits SPF to a maximum of 10 DNS lookups during evaluation. This includes all include, redirect, a, and mx mechanisms. Exceeding this limit causes a permerror result, and receiving mail servers will typically fail SPF for your domain.
SPF flattening is the process of resolving all include and redirect mechanisms to their final IP addresses, then replacing them with ip4/ip6 directives. This eliminates nested DNS lookups, keeping your SPF record under the 10-lookup limit.
SPF flattening is safe if done correctly and monitored regularly. The main risk is that ESPs can change their IP addresses, so you must re-flatten periodically or set up automated monitoring to catch changes. Some organizations use SPF compression services that handle this automatically.
If SPF evaluation requires more than 10 DNS lookups, the result is a permerror. Receivers that strictly enforce SPF will reject or mark your email as suspicious. DMARC treats permerror as a failure, which can cause your emails to be quarantined or rejected under a p=quarantine or p=reject policy.
No. A domain can only have one SPF record (one TXT record starting with "v=spf1"). Having multiple SPF records is a syntax error that causes SPF to fail. If you need to authorize multiple services, combine them into one record using include: directives, or flatten them into a single record with ip4/ip6 entries.
Check your SPF lookup count, identify which mechanisms are eating your lookups, and get specific flattening recommendations.
Free SPF Check โ