Views: 12

SPF Record: Check and Set It Up Correctly

SPF record check and setup: the three mistakes that break it — two records, +all, the 10-lookup limit — and how to fix each. Free instant check, no sign-up.

Check your domain for this issue now

Free, no sign-up. Runs the exact check this guide describes and shows what to fix.

Problem

You added a new mail service — Microsoft 365, a newsletter tool, your helpdesk — and it told you to “add this SPF record to your DNS.” So you added it, right next to the one that was already there. And now, quietly, everything is failing. Your legitimate mail lands in spam or bounces with a PermError, and the diagnostic you get back says something unhelpful about SPF.

Here’s the thing nobody tells you when they hand you that TXT record to paste: SPF is not a list of records you keep adding to. It’s a single record with strict rules, and the two or three ways people break it are always the same. Once you can see them, SPF stops being magic and becomes a five-minute check.

What an SPF record actually is

SPF — Sender Policy Framework, defined in RFC 7208 — is one DNS TXT record on your domain that answers a single question for the receiving mail server: is the machine trying to send this message allowed to send for this domain? It’s a published allowlist of your sending sources.

A minimal record looks like this:

v=spf1 include:_spf.google.com ~all

v=spf1 marks it as SPF. The middle is a list of mechanismsinclude:, a, mx, ip4:, ip6: — each naming a source that’s allowed to send. The trailing all is the catch-all: what to do with everything you didn’t list. The receiver reads this record, checks the connecting server against it, and returns a result: pass, fail, softfail, or the two that mean you’ve made a mistake — permerror and temperror.

The three mistakes that break SPF

Nearly every broken SPF record fails for one of three reasons. None of them show up as a syntax error you’d notice by eye.

1. Two records instead of one. RFC 7208 §3.2 is blunt: a domain publishes exactly one record starting with v=spf1. Two records is not “extra coverage” — it’s an immediate PermError, and PermError fails authentication for everything, even mail from servers both records would have allowed. This is what happens when you add a provider by pasting a second record next to the first. The rule you have to internalize: you merge, you never append. Adding Microsoft on top of Google means taking the includes from both and putting them in one line:

v=spf1 include:_spf.google.com include:spf.protection.outlook.com ~all

2. The 10-lookup limit. SPF evaluation may trigger at most 10 DNS lookups (§4.6.4), a cap that exists so a hostile record can’t turn every inbound message into a DNS flood. Each include, a, mx, ptr, exists, and redirect costs a lookup — and includes nest, so one include: that references three more spends four. A single big provider’s include can burn 3–5 lookups on its own, so three or four stacked providers is all it takes to cross the line and earn a PermError. The trap is that this record looks fine; it’s short, it’s valid, and it fails only because of what its includes pull in. There’s a second, quieter cap too: no more than 2 void lookups (mechanisms that resolve to nothing), which is how a dead include: pointing at a service you dropped years ago silently poisons the whole record.

3. Ending in +all. The all mechanism takes a qualifier: -all (fail), ~all (softfail), ?all (neutral), or +all (pass). +all says every server on the internet is authorized to send as me. People paste it to “make the errors go away,” and it does — by making SPF pass unconditionally, which is worse than publishing no SPF at all, because now anyone can forge your domain and clear the check. If you see +all anywhere in your record, that’s the bug.

How to read and check your record

The checking order is always the same, and it’s fast:

  1. Confirm there’s exactly one. Look up your domain’s TXT records and count how many start with v=spf1. If it’s more than one, that’s your problem before you look at anything else.
  2. Count the lookups, not the length. Walk each include, a, mx, and redirect, following includes into their own records, and add them up. Over 10 is a PermError waiting to happen; over 8 is a warning to start flattening.
  3. Check for dead ends. An include: or redirect that resolves to nothing burns your void-lookup budget. Drop mechanisms for services you no longer use.
  4. Read the all qualifier. ~all while you’re building the list, -all once it’s complete, and never +all.

When you add a new sender, the discipline is: find your existing record, add the new provider’s include, and republish the one record. Never leave two.

Check it with DechoNet

  • Email / SPF Check evaluates your domain’s SPF the way a receiving server does: it flags multiple records, counts the DNS lookups against the limit, resolves each include so you can see which one is bloated, and reads the final all qualifier. This is the fastest way to catch the PermError causes that don’t look like errors.
  • DNS Lookup shows the raw TXT records on the domain, so you can confirm with your own eyes that there’s exactly one v=spf1 line and nothing stale hiding beside it.

Resolution Checklist

  • Confirm the domain has exactly one v=spf1 TXT record. If there are two, merge them into one line — includes from both, published once.
  • Count the DNS-querying mechanisms (include, a, mx, ptr, exists, redirect), following nested includes. Keep the total under 10.
  • Remove include: or redirect entries for services you no longer send from — they waste lookups and can trip the void-lookup cap.
  • Make sure the record ends in ~all or -all, never +all.
  • After any change, re-check with Email Check and send a test message to confirm the result is pass, not permerror.

When to Escalate

  • If you legitimately send from more providers than 10 lookups can cover, you need SPF flattening — replacing include: chains with the resolved ip4:/ip6: ranges — but only with a tool or service that keeps those ranges up to date, because a provider changing its IPs will silently break a hand-flattened record.
  • If SPF passes but mail still fails DMARC, the problem is alignment, not SPF itself: the domain in your From: header has to line up with the SPF-authenticated domain. That’s a separate check.
  • If the record is correct and receivers still return temperror, that’s a transient DNS resolution failure on their side, not a record you can fix — retry before changing anything.

Related Tools

Related Guides

Share this guide

[Ad] Guide Detail Inline
← Back to All Guides