Email deliverability, DNS, SPF/DKIM/DMARC
Fix Multiple SPF Records Causing PermError on Receivers
RFC 7208 forbids more than one v=spf1 TXT record at the apex. Two or more produces PermError on every check. Merge into one record to fix.
What's happening
Section 4.5 of RFC 7208 explicitly states that a domain MUST have exactly one SPF record. When a receiver finds two or more v=spf1 TXT records on the apex, the spec requires it to immediately return PermError without evaluating either record. The receiver does not merge them, does not pick one, does not warn — it fails outright.
This situation arises almost exclusively from human error during ESP onboarding. The vendor's documentation says "add this TXT record", and the operator adds it as a new record alongside the existing one rather than editing the existing one. Cloudflare, Route 53, and Google Domains all allow multiple TXT records on the same name, so DNS does not prevent the mistake at publish time.
Symptoms are identical to other PermError causes: spf=permerror in headers, mail routed to spam or rejected by Gmail bulk-sender enforcement, DMARC alignment impossible. The diagnostic difference is that lookup count and syntax may both be fine — the records themselves are valid; the duplication is the problem.
Why it matters
Because PermError invalidates SPF entirely, the SPF leg of DMARC always fails. If DKIM is also misconfigured or breaks for forwarded mail, DMARC fails completely and a strict p=reject policy bounces all your mail.
Gmail's February 2024 sender requirements treat PermError as authentication failure for bulk senders (5,000+ messages/day) and apply both temporary throttling and permanent reputation damage. Microsoft 365 routes mail to junk with high SCL scores.
The deceptive part is that some mail still arrives in inboxes — receivers fall back to DKIM and reputation when SPF fails, so the problem is intermittent rather than total. Operators routinely run for months with multiple SPF records before noticing the deliverability impact.
Common causes
- ESP onboarding added a new TXT record instead of editing the existing one.
- Different teams (marketing vs. ops) each published their own SPF record.
- DNS migration copied records and added a new one without removing the old.
- Subdomain delegation copied parent SPF records and they collide on the apex.
- Manual cleanup attempt where the old record was renamed but never deleted.
Detect this on your site
Run a quick scan with the Email Checker. The tool surfaces this exact issue with the records and context needed to apply the fix below.
Open Email CheckerHow to fix it
- 1
Count current SPF records
Run dig +short TXT example.com | grep -c 'v=spf1'. The result must be exactly 1. Any other number is the bug. If it is 0, you have a missing record (different fix). If it is 2 or more, proceed.
- 2
List every SPF record verbatim
Run dig +short TXT example.com | grep 'v=spf1'. Copy each record into a notes file. Read every include and ip mechanism. Any duplicate includes between records can be deduplicated; mechanisms unique to one record must be preserved.
- 3
Build a single merged record
Combine includes and ip mechanisms from all records into one v=spf1 line. Deduplicate. Keep one all qualifier at the end (use the strictest you had — typically ~all initially, -all once stable). Verify the merged record stays under 10 DNS lookups using SPF Surveyor.
- 4
Delete redundant records at the registrar
In Cloudflare DNS / Route 53 / Google Domains / Namecheap, delete every TXT record that starts with v=spf1 except the one you want to keep, and update that one to the merged value. Set TTL to 300 during the change.
- 5
Verify with dig and a Mail-Tester probe
Wait 5 minutes for propagation, then run dig +short TXT example.com | grep -c 'v=spf1' and confirm the count is 1. Send a fresh test message to mail-tester.com — the SPF row should read "SPF passes" not "SPF permerror".
- 6
Monitor DMARC reports for one week
Enable rua= aggregate reports if not already configured. After one week, the spf=permerror count must be zero across all reporters. Any nonzero count indicates the merge missed something or a duplicate was reintroduced.
Example
; Before — two records, PermError example.com. IN TXT "v=spf1 include:_spf.google.com ~all" example.com. IN TXT "v=spf1 include:spf.mailgun.org ~all" ; After — one merged record example.com. IN TXT "v=spf1 include:_spf.google.com include:spf.mailgun.org ~all"
Two valid records become one PermError. Merge to fix.
Frequently asked
Publish a separate SPF record on the subdomain e.g. mail.example.com. SPF does not inherit from parent to child so subdomain records are completely independent. The one-record-per-name rule applies to each name separately.
Yes for chunking — DNS allows a single TXT record to contain multiple quoted strings concatenated by the resolver. That is one record. What you cannot do is publish two separate v=spf1 records on the same name.
No. SPF is published in your DNS not the ESP's. As long as the merged record contains every include the ESP requires your mail flow is unchanged. Verify with the ESP's own SPF check tool after publishing.
Related fixes
Email deliverability, DNS, SPF/DKIM/DMARC
Fix SPF PermError on Inbound Authentication Checks
Email deliverability, DNS, SPF/DKIM/DMARC
Fix SPF Too Many DNS Lookups (PermError 10-Limit)
Email deliverability, DNS, SPF/DKIM/DMARC
Fix SPF Syntax Error in Your TXT Record
Email deliverability, DNS, SPF/DKIM/DMARC
Fix Missing SPF Record on Your Sending Domain
Email deliverability, DNS, SPF/DKIM/DMARC
Fix Missing DMARC Record on Sender Domain