What is an SPF record and how do you set it up correctly?
Last updated: 25:10:2026
What SPF does
SPF (Sender Policy Framework, RFC 7208) lets a receiving mail server ask a simple question: is the server handing me this message allowed to send mail for this domain? The answer comes from a TXT record you publish in DNS. The receiver looks up the record for the domain in the message's envelope sender (theMAIL FROM address, which ends up in the Return-Path header), compares the connecting IP address against the list, and gets a result such as pass, fail or softfail.
Two things follow from that. SPF checks the envelope sender, not the From: address people see in their mail app - tying the two together is the job of DMARC alignment. And SPF breaks when a message is forwarded, because the forwarding server is not on your list. That is why SPF works best alongside DKIM, whose signature survives forwarding.
SPF record syntax
An SPF record is a TXT record on the domain itself (the apex, often written as @). It starts with the version tag and is followed by mechanisms, evaluated left to right until one matches:
Example SPF record for example.com
example.com. 3600 IN TXT "v=spf1 ip4:192.0.2.10 include:_spf.mailprovider.example ~all"| Mechanism | Matches when | DNS lookup |
|---|---|---|
ip4: | The sender IP is in the given IPv4 address or range (192.0.2.0/24) | No |
ip6: | The sender IP is in the given IPv6 address or range | No |
include: | The other domain's SPF record passes - how you authorize a mail provider | Yes |
a / mx | The sender IP is one of the domain's A/AAAA or MX hosts | Yes |
redirect= | Use another domain's SPF record instead of this one | Yes |
all | Always - the catch-all at the end of the record | No |
ip4:ip6:include:a / mxredirect=allEach mechanism can carry a qualifier: + pass (the default), - fail, ~ softfail and ? neutral. In practice the qualifier only matters on the final all. The ptr mechanism is deprecated - don't use it.
~all or -all?
The ending decides what happens to mail from servers you didn't list. -all (fail) says "reject anything else"; ~all (softfail) says "treat anything else as suspicious". Both are fine, and both are far better than having no SPF record at all.
- Once you publish an enforcing DMARC policy, most large receivers make the final decision from DMARC, so the practical difference between
~alland-allis small. - Some receivers reject on an SPF
-allfail before they ever evaluate DMARC or DKIM, which can cost you legitimately forwarded mail. That's why many providers, AnyMail included, generate~all. - If a domain never sends mail at all, publish
v=spf1 -allso nobody can use it. - Never use
+all(anyone may send as you) or?all(no opinion) - they defeat the purpose.
The 10 DNS lookup limit
To keep SPF checks cheap, a receiver will perform at most 10 DNS lookups while evaluating your record. Every include:, a, mx, exists: and redirect= counts - including the ones nested inside the records you include. Go over the limit and the result is permerror, which most receivers treat like a failure. A separate rule allows at most two lookups that return nothing ("void lookups").
To stay under the limit:
- Remove includes for services you no longer use - old newsletter or CRM tools are the usual suspects.
- Prefer
ip4:/ip6:for servers you run yourself; they cost nothing. - Send bulk or marketing mail from a subdomain (for example
news.example.com) with its own SPF record. Each hostname has its own SPF record, and the subdomain's lookups don't count against the apex. - Be careful with "SPF flattening" (replacing includes with the IPs they resolve to): it works until the provider changes its addresses, and then your mail starts failing silently.
One SPF record per domain
A domain may publish only one TXT record that starts with v=spf1. Two of them is a permerror, and it is the most common SPF mistake: someone adds a new provider by creating a second record instead of editing the first. If you send through more than one service, merge them into one record:
Wrong - two SPF records
example.com. TXT "v=spf1 include:_spf.provider-a.example ~all"
example.com. TXT "v=spf1 include:_spf.provider-b.example ~all"Right - one merged record
example.com. TXT "v=spf1 include:_spf.provider-a.example include:_spf.provider-b.example ~all"Other TXT records on the same name (domain verification tokens, for instance) are fine - only records starting with v=spf1 count.
Common SPF mistakes
Forgetting a sender
Invoices from your accounting tool, notifications from a web shop, a contact form on your website: everything that sends with your domain in the envelope sender needs to be covered, or its mail will fail SPF.
Expecting subdomains to inherit the record
SPF is not inherited. mail.example.com or shop.example.com need their own record if they appear as envelope senders.
Long records and quoting
A single string in a TXT record can hold at most 255 characters. Longer SPF records must be split into several quoted strings inside the same record, which receivers join without spaces - so put the break inside a mechanism boundary and keep the space at the end of the first part. Most DNS panels do this for you; see how to add DNS records at your registrar.
Typos that silently break the record
v=spf1 must be the very first thing in the record, mechanisms are separated by single spaces, and include: takes a domain name, not a URL. Use the deprecated SPF record type (type 99) and nothing will read it - SPF lives in TXT records only.
How to check your SPF record
Look the record up with dig TXT example.com +short (or nslookup -type=TXT example.com on Windows), or use the email authentication checker. Then send a message to an external mailbox and open the original headers: the Authentication-Results header shows spf=pass when everything is right. DNS changes can take as long as the record's TTL to reach every resolver, so allow some time before you re-test.
When you attach a domain to AnyMail, the dashboard shows the exact SPF record to publish and checks it for you. If you already have an SPF record for another service, add AnyMail's value to that record rather than creating a second one.
Let AnyMail handle these records for you
AnyMail generates the MX, SPF, DKIM and DMARC records for your domain, checks every one of them automatically and tells you exactly which record to fix - then hosts your inboxes, operated from the EU.