Fixing SPF PermError
A PermError means receivers gave up on your SPF record. The usual causes are too many DNS lookups, two v=spf1 records, or a syntax error. Any of them fails SPF for every message, whatever the sender.
Too many lookups
Count the lookups the way a receiver does. Each include:, a, mx, ptr, exists: and redirect= costs one, and so does each one inside an included record. For example:
v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:servers.mcsv.net include:sendgrid.net include:_spf.salesforce.com mx ~all
Six mechanisms on the surface. Counted the way a receiver counts them, as these providers publish their records at the time of writing:
| Mechanism | Lookups | Why |
|---|---|---|
include:_spf.google.com | 4 | The include, plus the three records it includes in turn |
include:spf.protection.outlook.com | 2 | The include, plus one nested include |
include:servers.mcsv.net | 1 | Addresses only |
include:sendgrid.net | 1 | Addresses only |
include:_spf.salesforce.com | 2 | The include, plus the exists: inside it |
mx | 1 | Your MX records |
| Total | 11 | One over the limit: receivers stop with a PermError |
Providers change their records, so the count moves without you touching yours. The SPF page counts it live for your domain.
Method 1: hosted SPF (Business and above)
After you activate your domain, the SPF page gives you the record to replace yours with. It carries your current senders, flattened:
v=spf1 include:spf.[your-unique-link] ~all
Google, Microsoft, Mailchimp and SendGrid become addresses in our record. Salesforce authorizes by exists: and stays an include, costing its own lookups. Addresses your old record lists as ip4: or ip6: are carried over; a bare mx or a is not. If your own mail server sends mail and your record names it only through mx, list its addresses as ip4: in your record before you activate. The page shows the lookup count today and after the swap. See Moving your SPF.
Method 2: move senders to subdomains
Send marketing or transactional mail from a subdomain (news.example.com) with its own SPF record. Its lookups no longer count against your main domain's record. Check that the provider aligns with the subdomain; see Alignment failures.
Two SPF records
Merge them into one. Keep one v=spf1, list every sender in it, and end it with one ~all or -all.