Skip to content

Reference guide

What is an SPF record?

SPF is the public list of servers allowed to send mail on behalf of your domain. One TXT record, read left to right, and it breaks for the same handful of reasons every time.

8 min readUpdated September 12, 2026

In short

An SPF record is a TXT record published at the root of your domain. It lists the servers allowed to send mail on your behalf. A receiving server matches the sending IP address against that list and gets one of three answers back: authorized, not authorized, or no opinion either way.

What SPF is for

Without SPF, any machine on the internet can open a connection and claim to be sending from your domain. SMTP, as designed, asks for no proof. SPF supplies that proof from the domain side: the owner publishes a list of recognized servers in DNS, and the receiving server checks it before accepting the message.

The check applies to the envelope address, the one the sending server gives during the SMTP handshake. That is not the address your recipient sees in their mail client: the two can differ, and that gap is exactly what forged mail exploits. SPF on its own therefore leaves the visible address unprotected; DMARC is what forces the two to line up.

Publish the record as TXT, at the root of the domain. A dedicated SPF record type once existed and was dropped: today, an SPF record published as anything other than TXT is read by nobody.

An SPF record, term by term

Here is a complete record as it appears in a DNS zone. Terms are read in order, and the first one that matches the sender's IP address decides the verdict.

example.com. 3600 IN TXT "v=spf1 include:_spf.example.net ip4:198.51.100.25 ip4:203.0.113.0/28 ~all"
  1. v=spf1The version

    Required, and always first. It is how a resolver tells the SPF record apart from the other TXT records on the domain, of which there are usually several.

  2. include:_spf.example.netBorrowing a provider's list

    The checking server fetches that second domain's SPF record and evaluates it in turn. Authorize a sending platform this way and you never have to track its IP addresses, which change without notice.

  3. ip4:198.51.100.25One authorized address

    One machine, given by its IPv4 address. No extra lookup: the answer is already in the record.

  4. ip4:203.0.113.0/28An authorized block of addresses

    Same thing for a range. Here, the sixteen addresses from 203.0.113.0 to 203.0.113.15. The prefix length after the slash sets the size of the block.

  5. ~allThe default verdict, last

    Anything that did not match earlier lands here. The tilde asks for a softfail: accept the message, but mark it. A hyphen would ask for an outright reject.

Order matters: evaluation stops at the first term that matches. A mechanism placed after all will never be read.

SPF mechanisms and what they cost

An SPF record is a sequence of terms. Some name addresses outright; others send the checking resolver back to DNS — and those lookups are counted.

TermWhat it namesDNS query
v=spf1The version. Required, at the head of the record.No
ip4:An authorized IPv4 address or CIDR block.No
ip6:An authorized IPv6 address or CIDR block.No
aThe A and AAAA addresses of the domain, or of a domain given after a colon.Yes
mxThe addresses of the domain's inbound mail servers. Handy when the machine that receives is also the one that sends.Yes
include:Another domain's SPF record, evaluated in turn. The term sending platforms hand you.Yes
exists:True if the constructed name answers with an A record. Used for advanced conditional rules; you will rarely need it.Yes
ptrA reverse lookup on the sending IP address. The standard itself discourages it: slow, unreliable, do not use it.Yes
redirect=Replaces the record entirely with another domain's. Ignored when an all term is present.Yes
exp=The explanation text returned when the check fails. Never used on success.No
allEverything else. Always the last term, preceded by its qualifier.No

The four qualifiers

Each mechanism can carry a sign saying what to do when it matches. With no sign, the most permissive one applies.

SignResultWhat the recipient does with it
+PassThe server is authorized. This is the default: a mechanism with no sign counts as a plus.
-FailThe server is not authorized and the domain stands behind that. Most recipients reject the message.
~SoftFailThe server is not authorized, but the domain does not want a rejection yet. The message goes through, usually flagged.
?NeutralThe domain takes no position. In practice, the same as publishing nothing at all.

End in ~all while you are still watching. Move to -all only once you are certain no legitimate sender has been left out.

The ten DNS lookup budget

This is the limit that brings down most SPF records. It is not advisory: past it, the check does not fail, it errors out permanently, and the domain ends up exactly where it would be with no record at all.

What is countedCeilingPast it
Mechanisms that query DNS10Permanent error. Evaluation stops dead and the result is unusable.
Names returned by an mx mechanism10Permanent error, even when the overall budget is not reached.
Names returned by a ptr mechanism10The remaining names are ignored.
Empty DNS answers2Permanent error. An include pointing at a domain with no SPF record is one of the commonest ways to trip this.
v=spf1 records on the same name1Permanent error. Two records are worth zero records.
Length of one TXT string255Split the record into several strings; the reading resolver joins them back together.

The ip4, ip6, all and exp terms cost nothing. Replacing an include with the address blocks it publishes therefore frees up budget — at the price of manual upkeep the day the provider changes its servers.

Check your own domain, right now

Enter a domain name: the tool reads its SPF, DKIM and DMARC records and tells you what each one allows.

No sign-up, no email required. You can paste a full address — we'll pull the domain out of it.

The four mistakes you find everywhere

  • Two SPF records on the same domain

    What causes it: Someone adds a provider by creating a second TXT record starting with v=spf1 instead of editing the one already there.

    What fixes it: Merge them into one record, carrying over the include and ip4 terms from both, then delete the duplicate.

  • SPF passes and the message still lands in junk

    What causes it: SPF validates the envelope address, not the address shown in the mail client. The two can belong to different domains and SPF will not care.

    What fixes it: Publish DMARC. Alignment is its job: it requires the address SPF validated and the address the reader sees to share a domain.

  • The record goes past ten lookups

    What causes it: Every tool plugged into the domain brings its own include, and some of those includes nest several more. The count climbs out of sight.

    What fixes it: Drop the providers that no longer send anything, then replace the most stable remaining include terms with the address blocks they publish.

  • Automatically forwarded mail fails

    What causes it: A forwarding rule keeps the visible address but re-sends the message from another server, which is of course not on the list.

    What fixes it: No SPF setting covers this case. The DKIM signature is what survives forwarding, and that is why the three protocols are set up together.

The questions that come next

SPF, DKIM, DMARC: what order do you set them up in?

SPF first: one TXT record, no side effects. DKIM next, on the sending platform. DMARC last, in monitoring mode, once the other two pass on every send you make.

Does a subdomain inherit the domain's SPF record?

No. The check runs against the exact name announced by the sending server. A subdomain that sends mail must publish its own record, and a subdomain that sends none is better off publishing v=spf1 -all.

Should a record end in -all or ~all?

Start with ~all and read your DMARC reports for a few weeks. Move to -all once no legitimate sender shows up as a failure. Do it the other way round and you cut off real mail before anyone tells you.

How long does a change take to apply?

As long as the TXT record's TTL, as you published it. Servers that already read the old value will keep it until it expires, and not a second longer.