← Frankys Web GitHub Contact

SPF Generator

Put an SPF record together step by step, without syntax errors.

Who may send for this domain?

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.com or spf.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 include instead of creating a second one.
  • Too many lookups. Four or five providers with one include each are enough to break the limit of ten.
  • -all set too early. Rejecting outright before every sending system is really listed loses legitimate mail. ~all is 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.