v=spf1 TXT record, it seems reasonable that receivers will read both and combine them. They don't. When a receiving mail server finds more than one SPF record on the same name, it stops evaluating and returns PermError. Mail from your hosting server then fails SPF, and so does mail from the new tool.
This mistake is easy to make because nothing visibly breaks when you save the record. The DNS editor accepts it, the new service's setup wizard may even show a green check, and mail keeps flowing. The damage only shows up later as spam placement, DMARC failures in aggregate reports, or bounces from strict receivers. At the support desk this usually arrives as a vague complaint that "email started going to spam," with no obvious link to the DNS change made a few days earlier.
Why receivers refuse to combine SPF records
v=spf1, and evaluates the result.
The SPF specification, RFC 7208, is explicit about this step. Exactly one SPF record is expected. Zero records gives a result of none. Two or more records give permerror, which means "permanent error." The receiver does not guess which record you meant, does not try to merge them, and does not pick the first one it sees.
There is a practical reason for this. DNS does not guarantee the order of records in a response, so "use the first one" would give different answers on different queries. Merging is also ambiguous. Each SPF record ends with an all mechanism such as ~all or -all, and two records could end with different policies. There is no safe way to decide which policy wins, so the specification makes the whole thing an error and leaves it to the domain owner to publish one clear record.
The word "permanent" matters too. A temperror suggests a DNS timeout that may succeed if retried. A permerror means the published data itself is broken, so retrying gives the same result.
What PermError does to real mail
p=quarantine or p=reject, those messages are now quarantined or rejected.
The point to remember is that the duplicate record doesn't just break the new service. It breaks SPF for the whole domain, including the mail that worked before the change.
Spotting duplicate records with dig
v=spf1. Run it against a public resolver, and also against one of the domain's authoritative nameservers so you see what the zone actually contains, not what a resolver has cached.
BASH
# All TXT records as a resolver currently sees them
dig +short TXT example.com
# Find the authoritative nameservers, then ask one directly
dig +short NS example.com
dig +noall +answer TXT example.com @ns1.example.netv=spf1 count as SPF. The key skill is telling two separate records apart from one record that has been split into several strings.
TEXT
# Illustrative output format: two separate SPF records (PermError)
"v=spf1 a mx include:_spf.provider-one.example ~all"
"v=spf1 include:spf.provider-two.example ~all"
# Illustrative output format: ONE record split into two strings (valid)
"v=spf1 a mx include:_spf.provider-one.example " "include:spf.provider-two.example ~all"v=spf1. That is the PermError case. In the second case, there is one line containing two quoted strings. Each string inside a TXT record is limited to 255 characters, so long SPF values are often split this way, and RFC 7208 tells receivers to join the strings without adding spaces before parsing. That is the only kind of "merging" SPF does, and it happens within a single record, not across records. Because the strings are joined directly, the space between mechanisms has to be inside one of the strings, as shown at the end of the first string above.
Also check that you're looking at the right name. SPF is checked against the envelope sender domain, which for some services is a subdomain such as bounce.example.com rather than the root domain. A v=spf1 record on that subdomain doesn't conflict with the one on example.com. A duplicate only matters when both records sit on the same name.
Merging into one valid record
v=spf1 record and move the new service's mechanisms into it. Take everything between v=spf1 and the all term from both records, remove duplicates, and end with a single all policy. Then delete the second record.
TEXT
# Before: two records on example.com
v=spf1 a mx include:_spf.provider-one.example ~all
v=spf1 include:spf.provider-two.example ~all
# After: one merged record on example.com
v=spf1 a mx include:_spf.provider-one.example include:spf.provider-two.example ~allall last and only once. Mechanisms are evaluated left to right, and anything after all is never reached. If the two records ended with different policies, such as ~all (softfail) and -all (fail), choose deliberately rather than keeping whichever happened to be in the record you edited. Moving to -all is a policy change, not just a cleanup.
Count DNS lookups. Mechanisms such as include, a, mx, exists, and the redirect modifier each cost DNS queries, and SPF allows a maximum of 10 per evaluation, counting nested includes. Two records that were each fine on their own can go over the limit once merged, which also produces a PermError. If that happens, see Why SPF Suddenly Returns permerror After Adding One More include for how to count and reduce lookups.
Check whether your control panel or DNS host manages SPF for you. Some panels create an SPF record automatically and may recreate or overwrite it when mail settings change. If yours does, make the merge through the panel's own SPF or email authentication setting instead of editing the raw TXT record. Otherwise your merged record may be replaced, or a second record may come back.
Don't use the deprecated SPF record type. The DNS record type that once existed specifically for SPF is no longer used. Receivers read TXT records, so the single record belongs in TXT.
Confirming the fix actually took
dig command. You should see exactly one v=spf1 value. Public resolvers may keep returning the old pair until the record's TTL (time to live) expires, so a check against 8.8.8.8 or 1.1.1.1 can lag behind. That's caching, not a failed change. The TTL column in the full dig answer shows how long resolvers may keep the old data.
Then send real mail. Send a test message from each source that uses the domain, such as the hosting server, the new service, and any other tool listed in the record, to a mailbox you control at a large provider. Open the original message source and find the Authentication-Results header. You want spf=pass for each sender. If you still see spf=permerror, either the receiver is still using a cached copy or something else is wrong, most often the 10-lookup limit. If SPF passes but DMARC still fails, look at alignment. The envelope sender domain the service uses may not match your From domain, and that is a separate problem from duplicate records.
Finally, if the domain publishes DMARC with a reporting address, watch the next few aggregate reports. They show SPF results per sending IP, which confirms the fix at a scale a single test message can't.
The habit worth building is simple. Whenever a new service says "add this SPF record," read that as "add these mechanisms to your existing SPF record." Before saving anything, run dig +short TXT on the domain, confirm there is only one v=spf1 line, and count the lookups. That check takes less than a minute, and it is much easier than tracing a domain-wide delivery problem back to a TXT record added days earlier.