Quick Answer

SPF permerror occurs when a receiving server can't evaluate your SPF record due to a permanent error — typically syntax mistakes, exceeding the 10 DNS lookup limit, or void lookup limits. Unlike temperror (temporary), permerror means your record is fundamentally broken and authentication will fail until you fix it. Check your record with MXToolbox, count DNS lookups, and verify syntax.

SPF Permerror: Causes and Solutions

By Braedon·Mailflow Authority·Troubleshooting·Updated 2026-06-10

What SPF Permerror Means

When a receiving server evaluates your SPF record and encounters a permerror, it means the record is permanently broken. The server can't determine whether to pass or fail the sender — it's simply unable to complete the check.

This differs from temperror, which happens when DNS is temporarily unreachable. Permerror means something is structurally wrong with your record itself.

Common Causes

1. Exceeding 10 DNS Lookups

SPF has a hard limit of 10 DNS lookups per evaluation. These mechanisms count toward the limit:

  • include: — 1 lookup + any lookups in the included record
  • a — 1 lookup
  • mx — 1 lookup + lookups for each MX record
  • ptr — 1 lookup (don't use this)
  • redirect= — 1 lookup

These do not count:

  • ip4: and ip6: — direct IPs, no lookup
  • all — no lookup

When your record exceeds 10 total lookups (including nested includes), you get permerror.

Example: If your record has include:_spf.google.com (2 lookups), include:spf.protection.outlook.com (1 lookup), include:sendgrid.net (1 lookup), include:mailgun.org (2 lookups), include:amazonses.com (1 lookup), and a few more — you're over the limit.

Practitioner note: I see this constantly with agencies running multiple ESPs. Every new tool adds an include, and nobody counts. By the time they call me, they're at 15+ lookups and wondering why authentication randomly fails.

2. Syntax Errors

Common syntax mistakes that cause permerror:

# Missing mechanism before ip4
v=spf1 ip4:192.168.1.1 include:_spf.google.com all
# Should be: ~all or -all

# Typo in mechanism
v=spf1 includ:_spf.google.com -all
# Should be: include:

# Invalid IP format
v=spf1 ip4:192.168.1 -all
# Should be: ip4:192.168.1.0/24 or ip4:192.168.1.1

# Multiple SPF records (creates error)
# Record 1: v=spf1 include:_spf.google.com -all
# Record 2: v=spf1 include:sendgrid.net -all
# Must combine into ONE record

3. Void Lookup Limit (More Than 2)

A "void lookup" happens when a DNS lookup returns zero results. SPF allows a maximum of 2 void lookups before returning permerror.

This happens when you include a domain that:

  • Has no SPF record
  • Points to a non-existent hostname
  • Returns NXDOMAIN

Example: include:old-service.example.com where that record no longer exists.

4. Recursive Loops

If your SPF record includes a domain that includes back to you (directly or through a chain), you get permerror.

# yourdomain.com SPF:
v=spf1 include:partner.com -all

# partner.com SPF:
v=spf1 include:yourdomain.com -all

# This creates an infinite loop = permerror

How to Diagnose

Step 1: Check Your Record

Use MXToolbox SPF Lookup or dmarcian SPF Surveyor:

  1. Enter your domain
  2. Look for "permerror" in results
  3. Note the specific error message

You can also check from the command line:

dig TXT yourdomain.com +short

If the output shows two records starting with v=spf1, that alone causes permerror — merge them into one record.

Step 2: Count DNS Lookups

MXToolbox shows total lookups. If you're at 10+, that's your problem.

To manually count:

  1. List every include:, a, mx, ptr, and redirect=
  2. For each include, recursively count its lookups
  3. Sum everything

Step 3: Validate Syntax

Check for:

  • Missing v=spf1 at the start
  • Missing mechanism before qualifier (-all, ~all)
  • Typos in mechanism names
  • Invalid IP ranges

How to Fix

Fix 1: Flatten Your SPF Record

Replace include: mechanisms with direct IP addresses:

Before:

v=spf1 include:_spf.google.com include:sendgrid.net -all

After flattening:

v=spf1 ip4:209.85.128.0/17 ip4:74.125.0.0/16 ip4:168.245.0.0/16 -all

The downside: you must update IPs when ESPs change them. Use tools like Auto SPF or dmarcian to automate this.

Practitioner note: Manual flattening works until it doesn't. I've had clients break their email when an ESP quietly added new IPs. If you flatten, set calendar reminders to verify quarterly — or use a dynamic solution.

Fix 2: Remove Unnecessary Includes

Audit every include:

  • Is this ESP still in use?
  • Is this service still sending email?
  • Can multiple services be consolidated?

Often, old includes from cancelled services linger in SPF records.

Fix 3: Use Subdomains

Move different senders to subdomains with their own SPF records:

  • marketing.yourdomain.com — marketing ESP
  • transactional.yourdomain.com — transactional ESP
  • yourdomain.com — primary email (Google/Microsoft)

Each subdomain gets its own 10-lookup limit.

Fix 4: Fix Syntax Errors

Correct the specific syntax issue:

  • Combine multiple SPF records into one
  • Fix typos in mechanism names
  • Ensure valid IP formats
  • Add missing qualifiers

Fix 5: Remove Dead Includes

If you have includes pointing to non-existent domains, remove them. Check each include manually to verify the target still exists and has an SPF record:

dig TXT _spf.oldesp.com +short

If it returns nothing, that include is causing void lookups. Remove it or update to the correct domain.

Practitioner note: I've seen void lookup errors from ESPs that got acquired and changed their SPF domains. The old include still works for SPF pass, but triggers void lookups in the chain. Always check ESP documentation after acquisitions.

Verifying the Fix

After making changes:

  1. Wait for DNS propagation (15-30 minutes)
  2. Run MXToolbox SPF Record Lookup
  3. Confirm: "DNS Lookup Count: X/10" where X ≤ 10
  4. Confirm: No syntax errors flagged
  5. Send a test email and check headers for spf=pass

Prevention

  1. Document your SPF record — keep a list of every include and why it's there
  2. Audit quarterly — count lookups and verify all includes resolve
  3. Test before publishing — use MXToolbox to validate before DNS changes
  4. Monitor DMARC reports — SPF failures show up in aggregate reports

If you're dealing with complex multi-ESP infrastructure and can't figure out how to stay under the lookup limit, schedule a consultation — I'll help you architect an SPF strategy that actually works.

Sources


v1.0 · March 2026

Frequently Asked Questions

What causes SPF permerror?

The most common causes are exceeding 10 DNS lookups, syntax errors (missing mechanisms, typos), too many void lookups (more than 2), recursive include loops, and missing or invalid modifiers.

How do I check if I have SPF permerror?

Use MXToolbox SPF lookup, dmarcian SPF surveyor, or Google Admin Toolbox. These show if your record returns permerror and identify the specific cause.

What's the difference between SPF permerror and temperror?

Permerror is a permanent error caused by a broken record that needs fixing. Temperror is a temporary DNS issue that may resolve on retry. Permerror fails every time until corrected.

Does SPF permerror affect DMARC?

Yes. When SPF returns permerror, DMARC treats it as a fail. If DKIM also fails and you're at p=quarantine or p=reject, your email will be quarantined or rejected.

How do I fix too many DNS lookups?

Use SPF flattening to convert include mechanisms to direct IP addresses, remove unnecessary includes, consolidate ESPs, or use a dynamic SPF service like Auto SPF or dmarcian.

Can I have multiple SPF records?

No. Multiple SPF records cause permerror. If you have two TXT records starting with v=spf1, delete one and merge the includes into a single record.

Want this handled for you?

Free 30-minute strategy call. Walk away with a plan either way.