SPF record syntax: every mechanism, qualifier and modifier explained

By TechCompare · Updated · How we check

The first matching term wins. List your senders first and end with ~all or -all, so mail from any other server gets a clear result.

An SPF record is one TXT record on your domain that starts with v=spf1 and lists the servers allowed to send mail for it. A receiver reads the terms from left to right and stops at the first one that matches the sending server. The sign in front of that term, like ~ or -, sets the result. If nothing matches, the result is neutral, which tells the receiver nothing at all.

Topic
SPF record syntax
SPF
Category
Email records
SPF, DKIM and DMARC

How this is calculated

The terms that match a server are called mechanisms:

  • ip4 and ip6 match an address or a range, like ip4:192.0.2.0/24. Without a /length they match one address.
  • a matches the addresses in a name's A or AAAA records, and mx matches the addresses of a domain's mail servers. Both check your own domain unless you name another, like a:mail.example.com.
  • include runs the SPF check of another domain, usually your email provider's, and matches when that check passes.
  • exists matches when a name has an A record. It's mostly used with macros, which build the name from details of the message.
  • ptr matches on the server's reverse DNS name. RFC 7208 says not to use it, because it's slow and unreliable.
  • all matches every server, so it goes last.

Each mechanism can carry a qualifier that sets the result when it matches: a plus sign (+) for pass, a minus sign (-) for fail, a tilde (~) for softfail and a question mark (?) for neutral. A term without one passes, so include:_spf.google.com means the same as +include:_spf.google.com. That's why most records only show a qualifier on all. ~all says mail from other servers probably isn't yours. -all says it isn't.

include trips people up. It doesn't paste the other record into yours. It runs that record as a separate check and only uses the answer: a pass counts as a match, and a fail or softfail just moves on to your next term. If the included domain has no SPF record at all, the whole check stops with a permanent error.

Two modifiers change how the check runs. redirect= hands the whole check to another domain's record, which helps when many domains share one policy. Receivers ignore it when the record has an all term anywhere. exp= points at a TXT record with a message a receiver may show when mail fails. Each one may appear only once, and receivers skip modifiers they don't know.

Some terms cost a DNS lookup: include, a, mx, ptr, exists and redirect. A check gets 10 in total, counting the ones inside included records, while ip4, ip6 and all are free. Size matters as well. RFC 7208 suggests keeping the name plus all of its TXT records under 450 bytes, so the answer fits in one UDP packet.

The DNS Lookup explains each term of a domain's SPF record in a dropdown, follows every include and redirect, and counts the lookups.

Verdict

Start with v=spf1, add ip4 and ip6 ranges for servers you run, then one include per email service, and end with ~all while you're still finding every sender. Some receivers reject on -all before they check DKIM, which can block forwarded mail that DMARC would pass, so move to -all only if that trade suits you. Skip ptr, and keep one SPF record per domain.

More DNS scenarios

TXT records
The free text record that holds verification codes, SPF, DKIM keys and DMARC policies.
View details
SPF vs DKIM vs DMARC
SPF checks the sending server, DKIM checks the message, and DMARC ties both to the From address.
View details
MX records
How senders find your mail servers, what the priority number does, and the null MX for domains that take no mail.
View details

Frequently asked questions

What's the difference between ~all and -all?
~all is softfail: mail from a server you didn't list is probably not yours, and receivers shouldn't reject it on that alone. -all is fail: it isn't yours, and a receiver may reject it. With DMARC in place, ~all is the safer pick, because a hard fail can get mail rejected before DKIM gets a chance to pass it.
Does the order of terms in an SPF record matter?
Yes. The receiver stops at the first term that matches, so nothing after all is ever read. Order also saves lookups: a match on an early ip4 term ends the check before any later include is fetched.
What does +all do?
It passes every server on the internet, so anyone can send mail as your domain and pass SPF. Never use it. ?all isn't much better, since a neutral result tells the receiver nothing.