Guides

Why a domain can only have one SPF record

Last updated 2026-09-04

A new provider tells you to add include:their-domain.com to your SPF record. There's already an SPF record in your DNS panel, so adding a second TXT record looks like the careful move. The old record stays as it was and the new sender gets what it asked for. Every DNS panel lets you save it, and both records stop working the moment you do.

Which record wins? Neither. A receiver that finds two returns permerror, and every sender in both records loses its pass.

Two records means permerror for both

The receiving server, at Gmail, Outlook or wherever you sent to, fetches the TXT records at your domain and keeps the ones starting with v=spf1. RFC 7208 section 4.5 says that if more than one comes back, the check returns permerror and stops. The receiver doesn't merge them and it doesn't pick one. It couldn't pick anyway, since DNS returns the two in whatever order it likes.

So the sender you just added doesn't pass, and neither does anything that passed yesterday:

example.com. TXT "v=spf1 include:_spf.google.com ~all" example.com. TXT "v=spf1 include:sendgrid.net ~all" result: permerror. Neither Google nor SendGrid passes.

The fix is one record holding both:

example.com. TXT "v=spf1 include:_spf.google.com include:sendgrid.net ~all"

Nothing bounces, so nobody looks

Permerror is a result, and RFC 7208 leaves it to the receiver what to do with one. Most accept the message. So on the day you add the second record, mail still arrives and the panel still shows two tidy rows. The cost turns up later.

What you've lost is the SPF pass. DMARC needs SPF or DKIM to pass and align, and after a permerror it gets no SPF pass from any sender in either record. Under p=none that only shows up in your aggregate reports. Under p=reject, every message without a valid DKIM signature starts bouncing. The first to go are the tools that never signed anything, like the invoicing app or the contact form on the website.

Check whether you have two

DNS panels list TXT records as unrelated rows, so two SPF records look like two ordinary entries. Query the name instead:

dig +short TXT example.com | grep v=spf1

Two lines back is the problem. This works on any domain, so you can run it on a client's before a migration.

Merge the two into one

Take every mechanism from both records, drop the duplicates, and end with a single all. Order doesn't matter for include: and ip4: terms. Two things do need a decision.

The first is the ending. If one record said -all and the other ~all, the merged record gets one of them. Pick ~all until you're sure the sender list is complete. Going to -all on a record that's missing a sender turns that sender's mail into bounces.

The second is the lookup count. The old records each had a budget of ten. The merged one has ten for both. Two records at six lookups each merge into one at twelve, which is a permerror for a different reason. The 10-lookup limit guide covers getting back under it.

Paste the merged record into the pre-flight before you publish it. It resolves the record against live DNS, counts the lookups it really costs, and lists any sender that passed under the old records and wouldn't under the new one. A DNS panel can't run that check, because there's nothing to read until you publish.

Subdomains get their own record

Different names get different records. A subdomain doesn't inherit its parent's SPF, so a domain sending from example.com and mail.example.com publishes one record at each name. That's two records on two names, and it's correct:

example.com. TXT "v=spf1 include:_spf.google.com ~all" mail.example.com. TXT "v=spf1 include:sendgrid.net ~all"

It's also a good answer when a bulk sender pushes you past ten lookups. Give it a subdomain with its own record and your main domain keeps its own budget. Mail from the subdomain aligns to the subdomain, which DMARC accepts under relaxed alignment and rejects under strict.

Once the merged record is live, the remaining question is whether it names every server that sends as you. The record won't tell you. DMARC aggregate reports list the sources that actually sent mail as your domain. Our weekly digest reads those reports and mails you what's in them, free for your first domain.

Run the ramp on real reports

Every step in this guide depends on a few weeks of aggregate reports. We parse them and mail you a weekly summary: the senders that used your domain, what failed, and when tightening the policy is safe. Paid plans email you the day a new source first fails. Your first domain is free.

Get the weekly digest

No card · 12+ months of history · The free plan does not expire

Questions

Can I have two SPF records if they are for different subdomains?

Yes. The limit is one record per name. example.com and mail.example.com are different names, so each gets its own record and neither inherits the other's. The failure is two records on the same name.

I added a second record and mail still works. Is it fine?

No. Permerror isn't a bounce, and most receivers accept the message anyway. What you've lost is the SPF pass. DMARC now sees no SPF pass from any sender in either record, so every message has to pass on DKIM alone. Under p=reject, anything unsigned starts bouncing.

Which record wins if I have two?

Neither. RFC 7208 section 4.5 says that finding more than one v=spf1 record returns permerror and stops there, so every server named in either record loses its pass.

Does a second TXT record break SPF even if it is not an SPF record?

No. A domain carries plenty of TXT records at the same name, like verification strings and site ownership tokens. A receiver only reads the ones that start with v=spf1. Two of those is a permerror.

DomainCanary is a DMARC monitoring service that turns your domain's aggregate reports into one weekly email.