Short answer
No. A domain can have only one SPF record. With two TXT records starting with v=spf1, receivers return a permanent error (permerror), so mail from the domain fails SPF (RFC 7208, section 4.5).
What to do: merge them into one record, each include: and ip4: once and a single all at the end, within 10 DNS lookups. How to merge them.
Mail settings only matter while the domain is registered. The domain expiration checker shows when yours runs out, straight from its registry. Free, no account. Check a domain
Check how many you have
List the domain’s TXT records and keep the SPF ones:
dig +short TXT letsencrypt.org | grep spf1
"v=spf1 include:_spf.google.com ip4:23.178.112.0/24 ip4:66.133.109.36 ip4:64.78.152.132 include:mail.zendesk.com include:_spf.intacct.com -all"
One line, so one record: that is how it should look. Captured on October 24, 2026, with DiG 9.10.6.
Two lines means two records. This is a test copy of example.com’s zone, served from our own machine, with the mistake this guide is about: an SPF record for Google Workspace, and a second one added later for Mailgun.
dig @127.0.0.1 -p 5399 +short TXT example.com
"v=spf1 include:_spf.google.com ~all"
"v=spf1 include:mailgun.org ~all"
Each looks fine alone. Together, they make SPF fail for every message from the domain.
Why two records fail
RFC 7208, section 4.5, says how a receiver picks the record: it keeps the TXT records that begin with exactly v=spf1, and “if the resultant record set includes more than one record, check_host() produces the “permerror” result.” It doesn’t try both, or pick one. A permerror means “the domain’s published records could not be correctly interpreted” and “definitely requires DNS operator intervention” (section 2.6.7).
So SPF can’t pass. With DMARC, a message then needs an aligned DKIM signature to pass (RFC 9989, section 4.4); mail that relies on SPF alone fails, and a policy of p=quarantine or p=reject asks receivers to treat it as suspicious or refuse it (section 4.7).
What doesn’t count as a second record:
- Other TXT records. Verification tokens like
google-site-verification=…sit beside the SPF record without trouble. - A subdomain’s own record.
mail.example.commay have its own SPF record; it applies to mail from that name, not fromexample.com. - An
include:. It points at another domain’s record; it doesn’t add a record to yours.
SPF records go only in TXT records (section 3.1). The old SPF record type (99) was removed from the protocol, so a record of that type doesn’t count, either as a second record or as the first.
Merge them into one record
Keep one v=spf1 at the start, every sender’s mechanisms once, and one all at the end:
example.com. 3600 IN TXT "v=spf1 include:_spf.google.com include:mailgun.org ~all"
- Mechanisms from both records, in any order:
include:,ip4:,ip6:,a,mx. Duplicates only cost lookups. - One
all, last. Anything after it is never read (section 5.1). If the two records ended differently,~all(soft fail) and-all(fail), pick the one you mean. - One
redirect=, if any, and only withoutall. A record with both ignores the redirect. - Delete the old records in the same change, so there is never a moment with two.
Stay within 10 lookups
Merging adds the two records’ lookups together. Each include, a, mx, ptr and exists, and a redirect, costs one DNS lookup, counting the records they include, and more than 10 is a permerror too (section 4.6.4). ip4, ip6 and all cost nothing.
An include can cost more than one, because the record it points at may include others:
dig +short TXT mailgun.org | grep spf1
dig +short TXT _spf.mailgun.org
"v=spf1 include:_spf.mailgun.org include:_spf.eu.mailgun.org -all"
"v=spf1 include:_spf1.mailgun.org include:_spf2.mailgun.org ~all"
include:mailgun.org leads to _spf.mailgun.org and _spf.eu.mailgun.org, and _spf.mailgun.org to two more: 5 lookups for that one include. include:_spf.google.com lists only addresses today, so it costs 1. The merged record above needs 6, which is fine; we counted each name on October 24, 2026. A record over 10 is fixed by removing senders you no longer use, or by replacing an include with the ip4: and ip6: ranges it stands for, if its owner says they don’t change.
Lookups that find nothing count against a second limit: more than 2 of them is also a permerror. They come from includes and a: or mx: entries for names that no longer exist.
Check the merged record
Run the dig command again: one line should start with v=spf1. Then send a message to an address at another provider and look at the Authentication-Results header it arrives with (RFC 8601): it should say spf=pass.
A record you just changed can take up to its old TTL to reach every receiver. Without +short, dig prints it, in seconds, in the second column:
dig TXT letsencrypt.org +noall +answer | grep spf1
letsencrypt.org. 300 IN TXT "v=spf1 include:_spf.google.com ip4:23.178.112.0/24 ip4:66.133.109.36 ip4:64.78.152.132 include:mail.zendesk.com include:_spf.intacct.com -all"
Here 300: five minutes. Captured on October 24, 2026, with DiG 9.10.6. A resolver that cached the record just before your change counts down from the TTL it got then, so it may show a smaller number.
Sources
All sources were checked on October 24, 2026. The command output comes from our own runs on that date, with DiG 9.10.6.
- RFC 7208: Sender Policy Framework (SPF), IETF, April 2014: section 2.6.7 (permerror), 3.1 (TXT records only), 4.5 (selecting records), 4.6.4 (the lookup limits) and 5.1 (
all). - RFC 9989: Domain-Based Message Authentication, Reporting, and Conformance (DMARC), IETF, May 2026: section 4.4 (identifier alignment) and 4.7 (the policy). It replaced RFC 7489.
- RFC 8601: Message Header Field for Indicating Message Authentication Status, IETF, May 2019: the Authentication-Results header.
- RFC 1035: Domain Names, Implementation and Specification, IETF, November 1987: TXT records and TTLs.