What you need
Access to your domain's DNS management and a complete list of every system that sends email on your behalf. The second point is the harder one: besides the mail server this includes newsletter tools, CRM and ticketing systems, shop software, monitoring and invoicing.
Step 1 — Create the TXT record
SPF is an ordinary DNS TXT record on the domain itself, not on a subdomain such as _spf. Depending on your provider you enter @, the domain name, or nothing as the record name.
Step 2 — Choose the right mechanisms
include:provider.com— pulls in a provider's SPF record. The preferred route, because the provider maintains their own IPs.ip4:1.2.3.4— authorizes a single IPv4 address. Networks work too:ip4:1.2.3.0/24.ip6:2001:db8::1— the same for IPv6. If you send over IPv6 you must list it, otherwise SPF fails for those connections.a— authorizes the IPs from the domain's A record.mx— authorizes your own MX servers. Only useful if those same servers also send.ptr— deprecated, slow and explicitly discouraged by RFC 7208. Do not use.
Typical examples:
Step 3 — Set the all qualifier
The final term declares what happens to every server not listed:
-all(hardfail) — nobody else is authorized. This is the goal.~all(softfail) — not authorized, but please only mark it. Defensible during rollout.?all(neutral) — no statement. Practically ineffective.+all— authorizes every server on earth. Never use this.
Start with ~all if you are unsure whether you have captured every sender, then switch to -all after two to four weeks of observing DMARC reports.
Step 4 — Stay within the lookup limit
This is the most common and most treacherous mistake. RFC 7208 permits a maximum of 10 DNS lookups when evaluating an SPF record. include, a, mx, ptr, exists and redirect all count — and they count recursively: an include: for a provider whose own record contains three further includes consumes four lookups.
Exceed the limit and the entire record returns permerror. It is not just the surplus part that fails but everything — including senders that used to work. Note that ip4: and ip6: consume no lookups.
When it gets tight:
- Remove
include:entries no longer in use — usually half of them. - Replace individual providers with their concrete
ip4:ranges, provided those are stable. - Move different sending systems onto their own subdomains (
news.yourdomain.com), each with its own SPF record and its own lookup budget.
A separate limit of 2 void lookups applies — queries that return nothing. An include: pointing at a deleted domain counts against it.
Common mistakes
- Two SPF records: a domain must have exactly one
v=spf1record. Two produce permerror. Merge everything into one record. - Record at the wrong level: SPF belongs on the domain you send from. If you send from
company.com, a record onwww.company.comdoes not help. - Forgotten subdomains: SPF is not inherited. Every sending subdomain needs its own record.
- String length: a single TXT string may not exceed 255 characters. Longer records must be split into several strings — most DNS interfaces do this automatically.
Testing
After publishing, it can take up to 24 hours depending on TTL before the change is visible everywhere. Then send an email to hello@analyzemy.email and you get the full SPF audit back: result, recursive lookup count with breakdown, void lookups, and every IP your record actually authorizes.