zonewatchdog

Guide

What is SPF?

SPF is a DNS record that lists which servers are allowed to send mail using your domain. Receivers check the sending server against that list and use the answer to decide whether the mail is genuine.

What it actually does

When a server receives mail claiming to come from you@example.com, it looks up a TXT record on example.com that starts with v=spf1. That record lists IP ranges and other domains whose senders are authorised. If the connecting server is on the list, SPF passes.

SPF checks the **envelope sender** — the address used in the SMTP conversation, which appears in the Return-Path header. It does **not** check the From address the recipient sees. That gap is precisely why DMARC exists.

How to read a record

A record is a series of terms. ip4: and ip6: authorise addresses directly. include: delegates to another domain's record, which is how you authorise a service like Google Workspace or Mailchimp. a and mx authorise the domain's own hosts.

Each term carries a qualifier. + allows (the default), - fails, ~ soft-fails, ? is neutral. The record ends with an all term that decides what happens to everyone not listed.

-all or ~all?

-all tells receivers to treat unlisted senders as forgeries. ~all says the same thing more quietly — the mail is suspicious but should probably still be delivered.

Start with ~all while you confirm your sender list is complete, then move to -all. ?all and +all provide no protection at all; +all actively vouches for every forger on the internet.

Example

A typical record for a domain sending through Google Workspace and Mailchimp

example.com.  3600  IN  TXT  "v=spf1 include:_spf.google.com include:servers.mcsv.net ip4:203.0.113.10 ~all"

The ten-lookup limit is what breaks real domains

RFC 7208 caps an SPF evaluation at ten DNS-consuming terms. include:, a, mx, ptr, exists: and redirect= each spend one, and every include: is followed recursively — so a record with three includes can easily cost nine lookups. Past ten, receivers stop evaluating, return a permanent error, and treat the check as failed. Mail that should pass does not. Nothing warns you, the record still looks correct, and the usual trigger is adding one more marketing tool. ip4: and ip6: terms are free, so flattening an include into explicit ranges is the standard fix.

Count the real lookups on your domain.

Check a domain