SPF Generator
Put an SPF record together step by step, without syntax errors.
An SPF record states which servers may send mail using your domain as the sender. It is a single TXT entry in DNS, and it is unforgiving about syntax: a misplaced space, an invented mechanism or a typo in an IP address can render it useless without any error message showing up anywhere. This generator therefore builds the record from guided input: you pick the building blocks, it puts them in the right order and validates every value before it goes in.
What the generator does
Line by line you state who may send for your domain. You pick the kind of entry from a
list and only type the value yourself, which rules out typos such as ipv4 instead
of ip4 and invented mechanisms from the outset. On offer are:
- ip4 / ip6: a single address or a whole network in CIDR notation. Costs no DNS lookup and is therefore the cheapest statement.
- a: the address your domain itself points to. Without a value it means your own domain, with a value another one.
- mx: the servers that accept mail for your domain. Useful when the same machines also send.
- include: a provider's SPF record, such as
_spf.google.comorspf.protection.outlook.com. That adopts their server list without you knowing it.
You then choose what should happen to every other server. Afterwards the finished TXT record is ready with its name and value.
Reading the result
Two figures sit below the record. The length in bytes matters because a TXT
entry in DNS consists of character strings of at most 255 bytes; longer records are allowed but
have to be split across several strings manually at some providers. The number of DNS
lookups matters more: SPF permits at most ten terms that cost a lookup, and
a, mx and every include count towards it. Exceed the
limit and checking servers abort the evaluation with a PermError, leaving your record as good
as absent.
The generator only counts what it can see. Whatever hides inside a foreign
include adds to that: a single include from a large provider can consume several
lookups internally. How many there really are is answered by the SPF Check, which resolves the
chain for real.
Background: what the RFC requires
RFC 7208 is authoritative. It prescribes that the record begins with v=spf1,
that terms are separated by spaces, and that evaluation runs left to right: the first matching
mechanism decides and nothing after it is even looked at. That is exactly why this generator
sorts the cheap statements (ip4, ip6) to the front and the expensive
ones behind them, which saves real lookups in everyday use.
Two things are deliberately not on offer. ptr is explicitly discouraged by RFC
7208 section 5.5: resolving it is slow, unreliable and puts load on other people's name servers.
And +all would allow every server in the world to send in your name; the entry
would be syntactically valid and the exact opposite of what SPF is for.
Common failure patterns
- More than one SPF record per domain. The most common mistake of all, and a
PermError according to the RFC: both records are then ignored. When you add a new provider,
extend the existing record with another
includeinstead of creating a second one. - Too many lookups. Four or five providers with one
includeeach are enough to break the limit of ten. - -all set too early. Rejecting outright before every sending system is
really listed loses legitimate mail.
~allis the safe intermediate step. - Forgotten senders. Newsletter services, ticket systems, monitoring and web shops often send under your domain yet appear on no list.
Once the record is in DNS, check it with the SPF Check: it resolves every
include chain, counts the actual lookups and shows which netblocks end up
authorised.
Common questions
- Do I really need an SPF record?
- Without SPF a receiving server has no way of telling whether mail carrying your domain as the sender is genuine. In practice such messages land in spam more often, and DMARC cannot be enforced meaningfully without SPF or DKIM. Even a domain that sends no mail at all benefits from a record: 'v=spf1 -all' states explicitly that nobody may send in its name.
- Should I use ~all or -all?
- Start with '~all' (SoftFail). Messages from unlisted servers are marked but not discarded, so you notice a forgotten sender without losing mail. '-all' rejects outright and in doing so breaks forwarding and mailing lists that pass the sender through unchanged. Once a DMARC policy is enforced, DMARC takes over enforcement anyway and '~all' is entirely sufficient.
- What does the limit of ten DNS lookups mean?
- RFC 7208 limits the number of terms that trigger a DNS query during evaluation: 'a', 'mx', 'include', 'exists' and 'redirect' count, 'ip4' and 'ip6' do not. Exceeding the limit aborts the evaluation with a PermError and the record has no effect. The limit applies to the whole chain, including whatever sits inside foreign include targets.
- Can I create several SPF records for one domain?
- No. A domain may have exactly one SPF record. Two records are a PermError according to the RFC, and then neither of them applies, a mistake that often goes unnoticed because nothing visibly breaks. When another service needs to send, add it as a further 'include' in the existing record.
- Where exactly do I enter the record?
- As a TXT entry on the domain name itself, not on a subdomain such as '_spf'. At most providers you enter '@' or the domain as the name and the generated text as the value. If the record exceeds 255 bytes it must be split into several strings; many interfaces do that for you.
- Why does the generator not suggest providers?
- Because providers change their include targets and a curated list is wrong sooner or later. Your provider states the correct value in their documentation; it usually looks like '_spf.google.com' or 'spf.protection.outlook.com'. Enter it as an include, then check the result with the SPF Check.
- Does the generator change anything in my DNS?
- No. It only produces a piece of text that you copy and enter at your DNS provider yourself. The generator does not query DNS for that either: it computes purely from your input, without a single network connection.