Back to blog

The DNS mistake that silently breaks every email you send

Most people would scroll past this, and I almost did, too. But during a recent security audit, I noticed something in the DNS records that made me double-check.

Two SPF records on the same domain with both starting with v=spf1.

SPF (Sender Policy Framework) is a DNS record that tells receiving mail servers which servers are authorised to send email on behalf of your domain. When someone receives an email from you, their server looks up your SPF record and checks whether the sending server is on the list. If it is, good. If not, the email fails SPF.

RFC 7208, the specification that governs SPF, is explicit: a domain must not have more than one SPF record.

If you have two, receiving mail servers do not try to merge them or pick the “better” one. They return a result called permerror. Not a fail, or a soft fail, but a permanent error.

That permerror means SPF evaluation is treated as inconclusive. Combine that with DMARC, and your legitimate emails can start failing authentication quietly. No bounce. No error message. No notification. The email goes to spam or disappears, and you have no idea.

How does this happen?

Usually, it happens through accumulation.

Someone sets up Zoho Mail and adds an SPF record. A year later, someone else sets up Brevo (Sendinblue) for marketing emails and adds another one. Neither person knew the first record existed.

The domain slips into a broken state that no one notices because delivery mostly still works. Email delivery is messy enough that messages often get through anyway, which hides the problem.

In this case, the records were:

v=spf1 include:zcsend.net ~all
v=spf1 include:zoho.com include:sender.zohobooks.com include:spf.sendinblue.com mx ~all

Two separate senders. Two separate records. Neither wrong on its own. Together, broken.

The fix is simple: delete both and create one merged record.

v=spf1 include:zoho.com include:sender.zohobooks.com include:spf.sendinblue.com include:zcsend.net mx ~all

One record. All senders included. ~all to softfail anything that does not match.

Five minutes to fix. Potentially years of silent degraded deliverability before it gets caught.

Check yours. Run:

dig +short TXT yourdomain.com | grep spf

If that returns more than one line, you have a problem.

Then while you are there, check your DMARC:

dig +short TXT _dmarc.yourdomain.com

If p=none, your DMARC exists but is not enforcing anything. p=none is monitoring mode: it collects reports but does not block or quarantine mail. The goal is to move to p=quarantine, then p=reject.

Most domains I look at have either no DMARC, a p=none that was set up and forgotten, or the duplicate SPF issue above. All three are fixable in under an hour, but none of them announce themselves.