If your invoices land in spam, or somebody has been sending email that pretends to come from your domain, SPF is usually the first thing worth checking. It is one line of text in DNS, it takes about five minutes to read properly, and a surprising number of them are quietly broken.

You can pull up any domain's record with the SPF Checker while you read this.

What SPF actually is

Sender Policy Framework is a published list of the servers allowed to send email for your domain. It lives in DNS as a TXT record. When a receiving mail server gets a message claiming to be from you@example.com, it looks up that record and asks a simple question: did this message arrive from one of the servers on the list?

Here is a real-shaped record:

v=spf1 include:_spf.google.com include:servers.mcsv.net ip4:203.0.113.15 ~all

Read left to right, that says: this is SPF version 1; Google's mail servers may send for us; so may Mailchimp's; so may this one specific IP address; anything else is suspicious but do not hard-fail it.

Reading each part

v=spf1 — the version tag. It must be first, and there must be exactly one SPF record per domain. Two records is not "extra safety", it is a permanent error, and receiving servers will treat the whole thing as invalid.

include: — delegates to another domain's SPF record. When you sign up for a mail provider they hand you an include, and their record then covers whatever IPs they use. This is why the include exists: their infrastructure changes without you having to touch your DNS.

ip4: and ip6: — literal addresses or CIDR ranges. Useful for your own mail server or a fixed relay.

a and mx — shorthand meaning "the servers this domain's A record points at" and "the servers listed in this domain's MX records". Convenient, but each one costs you a DNS lookup, which matters more than most people realise.

The bit everyone gets wrong: ~all versus -all

The final mechanism decides what happens to mail that came from somewhere not on your list.

  1. -all is a hard fail. Anything not on the list should be rejected.
  2. ~all is a soft fail. Anything not on the list is suspicious — usually treated as a spam signal rather than a rejection.
  3. ?all is neutral. It says nothing at all and is functionally the same as having no policy.
  4. +all means anyone may send as you. If you find this on a live domain, it is a mistake, and a bad one.

The usual advice is to end on -all, and eventually that is right. But moving there too early is how legitimate mail disappears. If your finance team still sends invoices through a system nobody documented, -all will kill those messages silently and nobody will find out for a week.

A sane progression: start at ~all, turn on DMARC reporting so you can actually see what is sending as you, wait a few weeks, and only then tighten to -all. Guessing costs you real email.

The 10-lookup limit, and why records break

This is the failure that catches people out, because the record still looks fine.

SPF permits a maximum of 10 DNS lookups when evaluating a record. Every include, a, mx, ptr and redirect costs one — and includes nest, so a provider's record that itself contains three includes costs you four, not one.

Go over the limit and the result is permerror. Not "mostly works". The whole record is treated as invalid, and with DMARC on top of it, your legitimate mail starts failing.

The trap is that this happens gradually. You add a helpdesk, a CRM, a newsletter tool, an invoicing system, and one afternoon the eleventh lookup appears and email breaks for reasons nobody connects to a DNS change made three weeks earlier.

If you are near the limit: drop providers you no longer use (there are almost always two or three), replace an include with explicit ip4: entries where the provider publishes stable addresses, and consider SPF flattening — with the caveat that flattening freezes someone else's infrastructure into your record, so it needs re-checking when they change.

What SPF does not do

Worth being blunt about, because SPF is often oversold.

SPF checks the envelope sender — the Return-Path used during the SMTP conversation. It does not check the From: address your recipient actually sees in their mail client. Those two can differ completely.

That means a message can pass SPF cleanly and still display a forged From: header. SPF alone does not stop somebody spoofing your brand. It is one of three parts, and on its own it is the weakest.

It also breaks on forwarding. If someone forwards your email, the forwarding server becomes the sender, is not on your list, and SPF fails through no fault of anyone involved. This is normal and expected, and it is one reason ~all exists.

Checking your own record

Run your domain through the SPF Checker. It will pull the TXT record, break down each mechanism, and flag the obvious problems. From a terminal, dig TXT example.com +short gives you the raw record, and the DNS Lookup tool does the same from a browser.

Four things to check, in order:

  1. Exactly one record starting v=spf1. Two is broken.
  2. Under 10 lookups. Count every include, and count what those includes contain.
  3. Every sending system is covered. List them out — mail provider, marketing tool, invoicing, helpdesk, monitoring alerts, that one legacy server.
  4. A meaningful ending. ~all or -all, never ?all, never +all.

Where SPF fits

SPF is one leg of a three-legged stool. DKIM cryptographically signs the message so tampering is detectable. DMARC ties SPF and DKIM to the visible From: address, tells receivers what to do on failure, and — the genuinely useful part — sends you reports on who is sending mail as you.

SPF on its own is worth having. SPF with DMARC reporting is what actually tells you what is going on.

Common questions

Can I have two SPF records?

No. Multiple v=spf1 TXT records on the same domain is a permanent error. Merge them into one line.

Does SPF stop people spoofing my domain?

Not by itself. SPF validates the envelope sender, not the visible From:. You need DMARC on top to connect the two.

What does ~all mean?

Soft fail. Mail from servers not on your list is treated as suspicious rather than rejected — typically a spam-score penalty.

Why does my SPF fail when mail is forwarded?

Because the forwarding server is now the sender and is not on your list. This is expected behaviour, not a misconfiguration.

Where to go next

  1. Check yours with the SPF Checker, then the DMARC Checker.
  2. Stuck on a specific record? Ask in the BitCops community — paste the record and someone will read it with you.
  3. Want the ground-up version? The Introduction to Cyber Security course is free and assumes no prior knowledge.
  4. We also publish walkthroughs on YouTube.