An SPF record is a single DNS TXT string that lists which servers may send mail for a domain - built from a handful of mechanisms, closed off with an all qualifier, and capped at 10 DNS lookups by RFC 7208.
What the generator builds
The form above assembles a v=spf1 record from the mechanisms you choose: one or more include: entries for hosted mail providers, direct ip4/ip6 ranges for servers you run yourself, optional a and mx flags that authorize the domain's own resolved hosts, and a closing all qualifier. Every field maps to a real SPF mechanism defined in RFC 7208 - there is no proprietary syntax involved.
The include field defaults to _spf.google.com because it is the most common single entry for domains on Google Workspace, but it is only a starting point - remove it and add whatever your actual mail providers publish (Microsoft 365, SendGrid, Mailgun, a transactional API, a helpdesk). Each provider's documentation states the exact include: value to use.
The record builds live as you edit the form and is ready to copy into a DNS TXT record at the domain's apex (the bare domain, not a subdomain) as soon as it reflects your actual sending infrastructure.
Mechanisms: include, a, mx, ip4, ip6
include: pulls in another domain's SPF record and evaluates it as if it were inlined at that point. It is the right choice for any hosted provider that manages and rotates its own sending IPs - you point at their record and they keep it current. Most business email and marketing platforms publish one specifically for this purpose.
ip4: and ip6: authorize a literal address or CIDR range directly, no lookup required. Use them only for infrastructure you control - a mail server on a static IP, an on-premises relay - since nothing updates them automatically if that address changes.
a and mx authorize whatever the domain's own A/AAAA or MX records resolve to, at evaluation time. They matter mainly for setups where the mail server sending the message is the same host the domain's A or MX record already points to; a domain that sends exclusively through a third-party provider usually needs neither.
~all vs -all: choosing the catch-all
The all mechanism must be the last one in the record and decides what happens to mail from any server not matched by the mechanisms before it. -all (hardfail) tells a receiving server to reject such mail outright. ~all (softfail) tells it to accept the message but treat it as suspicious, usually by nudging a spam score rather than bouncing it. ?all (neutral) carries no more weight than having no SPF record at all, and +all authorizes every server on the internet - the opposite of what SPF exists to do.
The generator defaults to -all, but a record that has not been fully mapped against real sending sources should ship with ~all first: watch mail flow and provider logs for a period, confirm nothing legitimate is being flagged, then switch the qualifier to -all once the include and ip4/ip6 list is complete. Publishing -all before every legitimate sender is accounted for is the single most common cause of an SPF rollout silently dropping real mail.
| Qualifier | Name | Effect on unmatched mail |
|---|---|---|
| -all | Hardfail | Rejected by the receiving server |
| ~all | Softfail | Accepted, marked suspicious |
| ?all | Neutral | No effect - same as no SPF record |
| +all | Pass | Authorizes any server - do not use |
The 10-lookup limit
RFC 7208 caps SPF evaluation at 10 DNS lookups per check. include, a, mx, ptr, and exists each consume at least one lookup; ip4 and ip6 consume none, since they require no resolution. The count is not just the mechanisms in your own record - an include: inherits every lookup the included provider's own record makes, so three or four providers chained together can exceed the limit even though your own record looks short.
Once evaluation exceeds 10 lookups, RFC 7208 requires a permerror result, and most receiving mail servers then treat the entire check as failed regardless of whether the actual sending IP was authorized. The fix is to trim unnecessary includes, drop a or mx mechanisms that are not actually needed, or replace an include with the literal ip4/ip6 ranges it resolves to - accepting that those ranges then need manual upkeep whenever the provider changes them.
Reading the record you built
The record starts with v=spf1 and reads left to right - the first mechanism that matches the connecting server's IP decides the outcome, so order rarely changes the result in practice since ip4/ip6/include/a/mx either match or fall through to the next mechanism, with all only ever matching last by definition.
Before publishing, check the copy button output against what you intend to authorize: every include: should correspond to a provider actually sending mail for the domain, every ip4/ip6 entry should be an address you control, and the all qualifier should match how confident you are that the list above it is complete. Once the record is live, run it through /spf-checker to confirm the DNS TXT record matches what you published and see the resolved lookup count against the RFC 7208 limit.
Common mistakes
- Publishing more than one SPF TXT record - RFC 7208 requires exactly one; a domain with two is treated as having none valid
- Leaving +all in place, which authorizes any server on the internet to send as the domain
- Forgetting a provider added later (a new CRM, invoicing tool, or marketing platform) that then sends mail failing SPF
- Chaining enough include: mechanisms to exceed the 10-lookup limit, causing a permerror on every message
- Publishing the record on a subdomain expecting the parent domain's SPF to apply - SPF is evaluated per exact hostname, with no inheritance
- Switching straight to -all without confirming every legitimate sender is already listed
FAQ
Where do I publish the record this generator produces?
As a TXT record at the domain's apex (for example example.com, not mail.example.com) with the host/name field set to @ in most DNS panels. A domain should have exactly one SPF TXT record.
Can I combine include and ip4 in the same record?
Yes. Mixing mechanisms is normal - for example include: entries for a hosted mail provider alongside ip4: for an internal relay you run directly, closed with a single all mechanism at the end.
What happens if I don't add an all mechanism?
RFC 7208 treats a record with no matching mechanism as a neutral result by default, which gives receivers no real signal either way. Always close the record with -all, ~all, or ?all rather than omitting it.
Should a records I generate use a and mx?
Only if the server actually sending your mail is the same host your domain's A or MX record resolves to. Domains that send exclusively through a third-party provider's own servers usually don't need either.
Does the order of mechanisms in the record matter?
Evaluation goes left to right and stops at the first match, so in principle order matters - but since ip4, ip6, include, a, and mx each only match their own specific senders, in practice the result is the same regardless of order, as long as all stays last.
How do I check the record actually works after I publish it?
Use /spf-checker to fetch the live TXT record, confirm it parses without errors, and see the resolved DNS lookup count - that catches both propagation issues and a lookup count creeping past the RFC 7208 limit.
Related tools
- Validate the record after publishing it - parses syntax and counts the resolved DNS lookups
- Build the DMARC policy that decides what happens to mail failing this SPF check
- Add the second authentication mechanism DMARC alignment checks alongside SPF
- Inspect a domain's full TXT record set to confirm no conflicting SPF entry already exists