sfw/fix
SPF PermError (2 records) high

SPF PermError — Multiple SPF Records on One Domain

Two v=spf1 TXT records on one domain is invalid, so receivers return PermError and SPF fails on every message.

What you see

Received-SPF: permerror (google.com: permanent error in processing during lookup of [email protected]: redundant SPF records found)
spf=permerror (domain example.com has multiple SPF records)

What’s actually happening

SPF fails for everything you send, regardless of which server it came from. Because the result is permerror rather than fail, some receivers treat it like a SoftFail and junk the mail, while stricter ones reject it. DMARC that relies on SPF alignment collapses too, so even mail that should pass starts failing authentication. The classic cause: someone added a second TXT record for a new vendor instead of editing the existing one.

Common causes

  • Two separate v=spf1 TXT records published at the same name — RFC 7208 forbids this and mandates PermError.
  • A new ESP's setup wizard told you to 'add this TXT record' and you created a second one alongside your existing SPF.
  • A migration left an old v=spf1 record in place while a new one was added.
  • Copy-paste duplication in the DNS zone, sometimes from a botched import.
  • Two records that look different (one for Google, one for a CRM) but both start with v=spf1, which is the disqualifier.

How to fix it

  1. Confirm there really are two recordsQuery TXT directly: dig +short TXT example.com (or nslookup -type=txt example.com). Count the lines that start with v=spf1. More than one is the bug. SPF tools will also say 'multiple records found.'
  2. Merge every mechanism into one recordCombine all the include:, ip4:, ip6:, a, and mx terms from both records into a single v=spf1 ... all string. Example: v=spf1 include:_spf.google.com include:sendgrid.net ip4:198.51.100.7 ~all. Keep exactly one all term at the end.
  3. Delete the redundant recordRemove the second v=spf1 TXT entry entirely so only the merged one remains. Leaving it 'just in case' re-triggers the PermError.
  4. Stay under the 10-lookup limit while mergingMerging two records often stacks includes and can push you past SPF's 10-DNS-lookup cap — itself another PermError. If you're close, flatten stable includes to ip4/ip6 ranges.
  5. Re-verify the result is passAfter TTL expires, send a test to Gmail and check spf=pass in 'Show original,' or run an SPF validator against the live domain to confirm a single, valid record.

Stop it recurring

Treat SPF as one record per domain — always edit the existing v=spf1 TXT instead of adding a new one when onboarding a vendor.

Related errors