By Ahmet Karaca · Updated · Checked against RFC 7208 (SPF) on
How an SPF record is built
Every SPF record starts with v=spf1. A receiver that finds several TXT records at your domain keeps only the ones that begin with exactly that version tag and ignores the rest, so the tag has to come first and be spelled precisely.
After the version come the mechanisms, separated by spaces. Receivers read them from left to right and stop at the first one that matches the connecting server's IP address. That is why the generator writes the entries that need no DNS query, such as ip4, before the includes, and always puts all last, where it catches every server nothing earlier matched.
Each mechanism can carry a qualifier that decides the result when it matches: + means pass, - fail, ~ softfail and ? neutral. A mechanism without a qualifier counts as +. In a typical record only the final all carries one; everything before it lists servers you want to pass.
The redirect= modifier hands the whole evaluation to another domain's record when nothing in yours matched. It suits a company that runs many domains from one shared policy. A receiver ignores redirect= if the record also contains all, so a record uses one or the other.
Mechanisms and when to use them
ip4andip6name an address or a CIDR range you control, such as an office mail server. They cost no DNS lookup, so they are the cheapest way to authorize a fixed machine.includeasks another domain's SPF record whether it would pass the server. This is how a hosted mailbox or a sending service is authorized. It costs one lookup, plus whatever the included record triggers in turn.amatches the A or AAAA addresses of a host name, andmxmatches the servers behind a domain's MX records. Both cost a lookup, andmxbreaks if the domain has more than 10 MX hosts. Use them only if those machines really send mail.existsbuilds a domain name, often from macros, and matches if it resolves. It allows complicated schemes built from parts of the envelope, costs a lookup every time, and is rarely needed in a small setup.ptrchecks the reverse DNS of the sending IP. RFC 7208 says it should not be published: it is slow, unreliable when DNS has errors, and puts load on the reverse-DNS servers. Replace it withip4,ip6or an include.
Example records
A business that sends only from Google Workspace needs a single include:
@v=spf1 include:_spf.google.com ~allMailbox provider only
A company on Microsoft 365 that also sends receipts through SendGrid and runs its own server at 192.0.2.25 lists all three. The address costs nothing; each include costs at least one lookup:
@v=spf1 ip4:192.0.2.25 include:spf.protection.outlook.com include:sendgrid.net -allMailbox, transactional sender and an own server
A parked or redirect-only domain that never sends mail should say so, which stops anyone from passing SPF with it. There is nothing to generate here; publish this value as it is:
@v=spf1 -allDomain that sends no email
Picking the ending
~all asks receivers to treat unlisted servers with suspicion but not to reject on SPF alone, which leaves room for a sender you forgot. -all states that unlisted servers are not authorized; choose it once reports show every legitimate source passing, and read how -all and ~all differ before you switch.
Limits that break records
- 10 DNS lookups. Every
include,a,mx,ptr,existsandredirectcounts, including the ones inside included records. One more and the result is a permanent error; fixing SPF "too many DNS lookups" covers how to cut them. - 2 void lookups. An
a,mxorexiststerm whose name returns no records is a void lookup. More than 2 also fails the record;a:ormx:entries for retired hosts are a typical way to get there. - 255 characters per string. Longer values are split into several strings that receivers concatenate without adding spaces.
- One record per domain. Two TXT records that start with
v=spf1return a permanent error for every message.
After publishing, run the domain through the SPF lookup counter in our SPF checker to see the nested total, and look at the Google Workspace SPF setup guide or the SendGrid setup guide for the provider side.