At a glance. Record type: TXT, one per domain · Starts with: v=spf1 · Read: Left to right, first match wins · Lookup limit: 10 DNS lookups
The short version
- How a record is read. An SPF record is a single line of text published as a TXT record.
- Qualifiers. A qualifier is a single character placed directly in front of a mechanism.
- Mechanisms that need no DNS lookup. The ip4 and ip6 mechanisms match a literal address or a range written in CIDR notation.
- Mechanisms that cost a DNS lookup. The include mechanism asks the receiver to evaluate another domain's SPF record and match if that record passes.
- Modifiers: redirect and exp. A modifier is written name=value and is not a test of the sending address.
- Length and format limits. Each string inside a TXT record can hold at most 255 characters.
How a record is read
An SPF record is a single line of text published as a TXT record. It must begin with the version tag v=spf1, followed by a list of terms separated by spaces. A receiving server evaluates the terms from left to right against the IP address that connected to it, and the first term that matches decides the result.
v=spf1 ip4:203.0.113.10 include:_spf.example.net ~all
If no term matches and there is no redirect, the result is neutral. That is why most records end with an all term: it matches everything, so the last word always says what to do with a server that is not on the list.
Qualifiers
A qualifier is a single character placed directly in front of a mechanism. It sets the result when that mechanism matches. With no qualifier, plus is assumed, so mx and +mx mean the same thing.
-all fail: not authorised
~all softfail: probably not authorised
?all neutral: no opinion
+all pass: everyone is authorised (never use this)
The four results are pass (plus), fail (minus), softfail (tilde) and neutral (question mark). Receivers usually treat fail and softfail as a negative signal rather than an instruction to reject, and DMARC decides what happens to a message that fails.
Mechanisms that need no DNS lookup
The ip4 and ip6 mechanisms match a literal address or a range written in CIDR notation. They are the cheapest part of a record because the receiver has nothing to look up, and they are the safest choice when a provider publishes fixed sending addresses.
ip4:203.0.113.0/24
ip6:2001:db8::/32
all
The all mechanism matches every address. It belongs at the end. Terms written after it are never reached.
Mechanisms that cost a DNS lookup
The include mechanism asks the receiver to evaluate another domain's SPF record and match if that record passes. The a mechanism matches the address records of a domain, and mx matches the addresses of its mail servers. Both default to the domain being checked, and both accept a domain and a CIDR length. The exists mechanism matches if a name resolves, and ptr matches by reverse DNS.
include:_spf.example.net
a
a:mail.example.com/24
mx
exists:%{i}._spf.example.com
Each of include, a, mx, ptr and exists, and the redirect modifier, counts toward the limit of ten DNS lookups, and includes inside includes count too. The standard also caps the mx mechanism at ten mail servers. The standard discourages ptr because it is slow and unreliable, so avoid it.
Modifiers: redirect and exp
A modifier is written name=value and is not a test of the sending address. The redirect modifier says: ignore the rest of this record and use the record at another domain instead. It is only consulted when no mechanism has matched, and a record that has an all term never reaches it.
v=spf1 redirect=_spf.example.net
The exp modifier names a domain whose TXT record holds an explanation string that receivers may show when SPF fails. Most domains never use it. Each name may appear at most once in a record.
Length and format limits
Each string inside a TXT record can hold at most 255 characters. A longer record is stored as several strings that receivers join together, and most DNS panels split a long value for you. A very long record can also exceed the size of a normal DNS reply, which is one more reason to keep the list short.
Terms are separated by one or more spaces and are not case sensitive. Keep the record on one TXT record: a domain with two SPF records gets a permanent error.
Syntax errors that break a record
Most failures come from a handful of slips: a missing v=spf1, an include without a domain, a misspelled mechanism such as inlcude, an address with a mistake in it such as ip4:203.0.113.300, or a stray character from a copy and paste. Any of them makes the whole record invalid and the result a permanent error.
Test before you publish. Our SPF checker reads a pasted record, marks each problem and counts the DNS lookups, so you can fix a record before it goes live.
Further reading and sources
Do it in MigoSMTP: help-center articles
- Fix SPF permerror and the 10-lookup limit
- Authenticate a sending domain in MigoSMTP: SPF, DKIM and DMARC
- Verify your sending domain: DNS records and propagation
Related guides and tools
- SPF record checker: Paste a record or check a domain.
- SPF record generator: Build a record that stays inside the limit.
- How to create an SPF record: The step-by-step guide.
- SPF record examples: Workspace, Microsoft 365 and more.
Not sure your records are right? Run our free checker, or send us a header and we will help you read it.
Frequently asked questions
What is the syntax of an SPF record?
An SPF record is one TXT record that starts with v=spf1, followed by terms read from left to right, and usually ends with an all term. Each term is a mechanism such as ip4, include, a or mx, optionally preceded by a qualifier that sets the result.
What do the plus, minus, tilde and question mark mean in SPF?
They are qualifiers. Plus means pass and is the default, minus means fail, tilde means softfail and question mark means neutral. They go directly in front of a mechanism, for example -all or ~all.
Which SPF mechanisms count toward the 10 lookup limit?
The include, a, mx, ptr and exists mechanisms and the redirect modifier each count. The ip4, ip6 and all mechanisms do not need a DNS lookup, so they do not count.
What happens to terms written after the all mechanism?
They are never evaluated, because evaluation stops at the first term that matches and all matches everything. Put all last.