How to Fix SPF PermError in 2026
If your SPF record exceeds the 10-DNS-lookup limit, receiving mail servers will reject it with a PermError - a permanent error. Your email doesn't get a soft fail. It gets a hard stop.
Here's what causes it, how to detect it, and how to fix it for good.
What is SPF PermError?
SPF (Sender Policy Framework) lets domain owners specify which mail servers are authorized to send email on their behalf. The SPF specification (RFC 7208) imposes a hard limit of 10 DNS lookups during SPF evaluation.
When your record exceeds this limit, the receiving mail server returns a PermError and stops processing the SPF check entirely. The result varies by receiver:
- Strict receivers (Gmail, Outlook.com) - treat it as SPF fail
- Lenient receivers - treat it as neutral or softfail
- Either way - your deliverability takes a hit
Why does this happen?
The 10-lookup limit is easy to hit because SPF include: statements count as one lookup each - but they can also nest
more lookups inside them.
Common culprits:
- Google Workspace (
include:_spf.google.com) - adds ~4-5 lookups internally - Microsoft 365 (
include:spf.protection.outlook.com) - adds ~2-3 lookups - Mailchimp, SendGrid, Mailgun, Mandrill, HubSpot, Salesforce - each adds at least 1 lookup
- Custom
a:ormx:mechanisms with multiple A/AAAA records
A typical mid-size company using Gmail, Outlook, Mailchimp, and one CRM is already at 8-12 lookups on paper - but the actual chain often goes well past 15 once nested includes are resolved.
How to detect it
Option 1: Use the SPFlat! checker (free, no signup)
Go to spflat.cloud, enter your domain, and hit Check. The tool resolves your full SPF chain including all nested includes and shows you exactly how many lookups you're consuming.
Option 2: Manual dig chain
dig TXT yourdomain.com +short | grep -o 'include:[^ ]*' | while read inc; do
dig TXT ${inc#include:} +short
done
This gives you a rough count but misses nested recursion unless you script deeper loops.
Option 3: Online SPF validators
Tools like dmarcian.com or mxtoolbox.com can help, but many cap at 10 lookups and stop resolving - which gives you a false sense of security.
How to fix it (the hard way)
If you want to do this manually:
- Resolve every
include:,a:,mx:, andptr:in your record - Collect all resulting IP addresses and CIDR ranges
- Build a new record with only
ip4:andip6:mechanisms - Publish it in your DNS
Before:
v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:mailgun.org ~all
After manually flattening:
v=spf1 ip4:209.85.128.0/17 ip4:40.92.0.0/15 ip4:209.61.151.0/24 ~all
How to fix it (the smart way)
This is exactly what SPFlat solves:
- Check your domain on spflat.cloud - see your current lookup count instantly
- Add your domain to SPFlat! with your current includes
- Publish one DNS record - SPFlat! monitors provider IP changes 24/7 and keeps your record updated automatically
No manual lookups. No spreadsheets tracking IP changes. No late-night debugging when Google rotates their ranges.
Prevention
Once your SPF is flattened, keep it clean:
- Add new email services through SPFlat! - don't modify the TXT record directly
- Monitor DMARC reports - a sudden dip in SPF-aligned messages is often the first sign of a provider IP change
- Use automated monitoring - SPFlat watches your records with 99.9% uptime across 12 global locations
🔍 Check your domain now
Ten seconds. Free. See exactly how many lookups your SPF record consumes - including all nested includes.
Check Your SPFOr start your free 14-day trial →
