What the problem is
A domain may have only one SPF record. RFC 7208 (section 4.5) says that if a DNS lookup finds more than one TXT record starting with v=spf1, the result is permerror. Receivers don't pick one or combine them; SPF simply fails to evaluate for every message. With DMARC, that means you lose SPF as a way to pass, and mail that isn't DKIM-signed with your domain fails.
example.com. TXT "v=spf1 include:_spf.google.com ~all"
example.com. TXT "v=spf1 include:spf.esp.example.net ~all"
In headers you see something like:
Authentication-Results: mx.example.net;
spf=permerror (multiple SPF records) smtp.mailfrom=example.com
The text in parentheses varies by receiver. Paste a received message into the Email Header Analyzer to see the result.
How it happens
- A new service's setup guide says "add this TXT record", and someone adds a second
v=spf1record instead of editing the existing one. - Switching providers: the new record is added, the old one never removed.
- DNS host templates that create a default SPF record when you turn on email forwarding or a mail product.
- Split records: a long record broken into two TXT records by mistake. A long record should be split into several strings inside one TXT record, not several records.
Other TXT records on the same name are fine. Verification tokens, google-site-verification= and similar entries can sit next to your one SPF record. Only records starting with v=spf1 count. The old SPF record type (type 99) is obsolete and should be removed if it is still there.
How to fix it
Merge every mechanism into one record, with one v=spf1 at the start and one all at the end:
example.com. TXT "v=spf1 include:_spf.google.com include:spf.esp.example.net ~all"
Steps:
- List all TXT records on the domain:
dig +short TXT example.com. - Collect every
include,ip4,ip6,aandmxterm from the SPF ones, dropping duplicates and services you no longer use. - Pick one qualifier for
all(see softfail vs fail). - Create the merged record, then delete the others.
- Count the lookups. Merging often pushes a record past the limit of 10; see too many DNS lookups.
Long records
A single TXT string can hold at most 255 characters. If the merged record is longer, put it in one TXT record made of several quoted strings; receivers join them without spaces, so put the space inside a string:
example.com. TXT ( "v=spf1 include:_spf.google.com include:spf.esp.example.net "
"ip4:192.0.2.0/24 ip4:203.0.113.10 ~all" )
Most DNS control panels handle the splitting for you when you paste a long value.
Subdomains are separate
SPF records don't inherit. example.com and mail.example.com each have their own record, and each may have exactly one. A subdomain without a record returns spf=none for mail using it as the envelope sender.
Related
- SPF too many DNS lookups: the other common permerror.
- spf=none: when there is no record at all.
- TXT record: how TXT records and their strings work.
- SPF record: full syntax.
Check whether your domain has one valid record with the SPF Checker.