Advertisement
Every include resolved live

SPF Record Generator
that counts your real DNS lookups

A free SPF record generator that does the part other builders leave to you. Pick your senders, or import the record you already publish, and get a valid record back. Every include: is resolved live and its chain counted against the ten-lookup limit — not read from a table that went stale when your provider last changed their record.

Build an SPF record, or rebuild the one you have

Tick the services that send mail for your domain. Add any servers of your own as IP addresses — those cost no lookups at all. The counter updates from live DNS every time you build.

Import reads the record you publish today and fills the builder with it, so you can see what it really costs and edit it down. Nothing is stored.

Services that send your mail

No lookup costs are printed next to these names on purpose. When we measured these fifteen includes against live DNS, the most complete published table we could find disagreed on ten of them — so the real number is resolved when you build.

One per line. IPv4, IPv6 and CIDR ranges. Anything invalid is refused rather than written into the record.

One per line. The include: prefix is added for you. Each one is resolved to check it publishes an SPF record at all.

Your own servers
What should receivers do with everyone else?
Advanced — hand evaluation to another domain

Using redirect= replaces the all term entirely — RFC 7208 §6.1 says a redirect “MUST be ignored if there is an ‘all’ mechanism anywhere in the record”. Leave this empty unless several domains share one policy.

Quick Answer: how do I create an SPF record?

List every service that sends mail for your domain, then publish one TXT record at the domain in the form v=spf1 followed by an include: for each provider, ip4: for any servers of your own, and ~all or -all at the end. The one rule that breaks most records: the whole thing may cost at most ten DNS lookups, counting the includes inside your providers’ records too. The builder above resolves each one live and tells you the real number.

Advertisement
Robert Harrison, OSINT & Network Utility Expert, on building SPF records at TrustMyIP.com
Written & Verified By

Robert Harrison

OSINT & Network Utility Expert

Works on DNS records, network utilities and the developer tooling around them — the same lane as the SPF checker, DMARC checker and DNS lookup on this site.

This builder resolves provider costs instead of printing them because the printed ones are wrong. Measuring fifteen provider includes against four independent public resolvers in September 2026 found the leading published table disagreeing with live DNS on ten of them — _spf.google.com costs one lookup, not the four every table still prints, because Google inlined its netblocks. One provider was under-counted, which is the direction that lets you publish a record already over the limit. The counting logic was checked against 118 test cases before it went near a real domain.

Last reviewed 22 September 2026 · Published 22 September 2026

View all articles by Robert Harrison
Advertisement

What an SPF record is, and what this builder does differently

An SPF record is one line of text in your DNS that names every server allowed to send email using your domain. When a message arrives claiming to be from you, the receiving server reads that record and checks whether the machine that just connected is on your list. SPF is defined in RFC 7208, and the record lives as a TXT record at the domain itself.

Here is a record with every part named:

v=spf1 ip4:203.0.113.5 include:_spf.google.com include:sendgrid.net ~all

PartWhat it doesDNS lookups
v=spf1Marks this TXT record as an SPF record. Must come first, and must be exactly this.0
ip4:203.0.113.5Authorises one address or range directly. The cheapest possible term.0
include:_spf.google.comAuthorises whatever that domain authorises. Pulls in their whole record, including any includes inside it.1 plus their chain
~allWhat to do with everything else. ~ softfail, - hard fail, ? neutral.0

That third row is where records break. An include: does not cost one lookup — it costs one lookup plus every counted term inside the record it pulls in, and inside theirs, all the way down. You cannot see that cost by looking at your own record, which is why a record that reads as four lines can quietly need fifteen lookups.

Key fact: RFC 7208 §4.6.4 sets a hard ceiling: implementations “MUST limit the total number of those terms to 10” and “MUST return permerror” if it is exceeded. A permerror is not a partial failure — SPF stops working for every recipient, including the servers you listed correctly.

Why this builder resolves instead of estimating

Most SPF generators are forms. You tick boxes, they join strings together, and you paste the result into DNS. The better ones print a lookup cost next to each provider from a stored table. That table is the problem.

In September 2026 we resolved fifteen provider include hosts against four independent public resolvers and compared the result with the most complete published table we could find. It disagreed on ten of the fifteen. The clearest case is Google: every table prints four lookups for Google Workspace, because _spf.google.com once contained three nested include:_netblocks terms. It does not any more — it lists IP ranges directly, and costs one. Microsoft 365 is published as two and measures one. SendGrid is published as five and measures two.

Over-counting is annoying: it pushes people into flattening records that never needed it. Under-counting is dangerous, and we found that too — one provider published as a single lookup measured two, which is how a builder tells you that you are inside the limit when you are already over it. A stored table cannot tell you which way it is wrong. A live resolution cannot be wrong about today, because it is today.

How to use the SPF record generator

Two ways in, depending on whether you are starting fresh or fixing something that broke.

Advertisement
  1. Start from what you publish now. Put your domain in the first field and press Import. The builder reads your live record, fills itself in with it, and shows you what each term really costs. If you are here because a record stopped working, this is the fastest route — you see the bill before you decide what to cut.
  2. Or tick your senders. Building from scratch, select every service that sends mail using your domain. Not just your mailbox provider: invoicing, helpdesk, marketing, CRM, monitoring alerts and anything that sends a password reset all need to be on the list, or their mail fails.
  3. Add your own servers as IP addresses. Anything with a fixed address — your own mail server, a VPS that sends application mail — belongs in the IP box. These cost zero lookups, so they are always the cheapest way to authorise something.
  4. Add anything else as an include. One hostname per line. Each is resolved to confirm it actually publishes an SPF record; if it does not, it is refused rather than written into your record.
  5. Choose what happens to everyone else. ~all while you are still discovering your senders, -all once the list is complete. Section four below explains why the order matters more than the choice.
  6. Read the counter, then publish. If it is in the green you are inside the limit. Copy the record into a TXT record at your domain, wait for the TTL, then confirm it with the SPF record checker, which reads what you actually published rather than what you intended.

Tip: the address bar carries your whole build. Send that link to whoever manages your DNS and they will see the same record, the same count and the same warnings — recalculated live when they open it, so it stays honest if a provider changes their record in the meantime.

Reading the lookup count

The counter is the only number on this page that decides whether your record works. RFC 7208 §4.6.4 names exactly which terms are counted, and the list is shorter than people expect.

Costs a lookupCosts nothing
include: · a · mx · ptr · exists: · redirect=
and include and redirect then recurse into whatever they point at
ip4: · ip6: · all · exp=
the RFC notes exp is only resolved later, after evaluation

So a record with twenty ip4: ranges and one include costs one lookup. A record with four includes can cost fifteen. Length has nothing to do with it.

Which term is costing you what

A total on its own does not tell you what to do about it. Once you build, the SPF record generator lists every term that costs a lookup, what it costs, and what share of your ten it is using — alongside the record it resolved to and the names it pulls in behind the scenes.

That is usually the moment the problem becomes obvious. A record at sixteen lookups is rarely sixteen small costs; it is normally two providers eating three quarters of the budget while five others cost one each. You do not need to redesign your mail estate, you need to deal with those two. None of the other generators we could inspect shows this breakdown, which is why “over the limit” usually arrives as a number with no instruction attached.

The second limit nobody counts

There is a separate cap that almost no generator mentions and no ranked SPF builder we examined counts at all. RFC 7208 §4.6.4 also says implementations “SHOULD limit void lookups to two” and that exceeding it “produces a permerror result”. A void lookup is a term whose DNS query comes back with nothing — either an empty answer or a name that no longer exists.

This matters because it fails records that are comfortably inside the ten. The usual cause is an include for a service you stopped using: the contract ended, they removed the record, your DNS still points at it. Three of those and SPF permerrors even though you are only at six lookups. The builder counts them and shows the total next to the main counter.

Two smaller rules worth knowing

The same section adds two limits that behave differently from each other, and the RFC explains why. An mx term “MUST NOT result in querying more than 10 address records”, and going over is a permerror. A ptr term has the same cap, but there “all records other than the first 10 MUST be ignored” — no error, just silent truncation. The asymmetry is deliberate: you control your own MX records, but you do not control the PTR records of whoever is connecting to you.

Limit: this count is correct for the moment you pressed build. Your providers can add an include to their own record tomorrow and push you over without touching your DNS. That is not a flaw in the counting — it is the reason to leave headroom rather than sit on exactly ten.

Choosing between ~all, -all and ?all

The last term tells receivers what to do with a server that is not on your list.

TermMeansUse it when
~allSoftfail — mark the message, do not reject itYou are still finding your sending sources, or DKIM is not signing yet
-allHard fail — the message is not authorisedYour list is complete and DKIM is signing every stream
?allNeutral — no opinion at allAlmost never. It is barely different from having no record
+allAuthorises the entire internetNever. This builder will not produce it

The usual advice stops at “-all is stronger, so get there eventually”. That is incomplete, and the specification that changed it is recent enough that most guides have not caught up.

What RFC 9989 changed in May 2026

DMARC was re-published as RFC 9989 in May 2026, replacing RFC 7489. Section 7.4 contains a sentence that reorders this whole decision: a domain publishing p=reject “MUST NOT rely solely on SPF to secure a DMARC pass and MUST apply valid DKIM signatures to their messages”.

The reason is forwarding. SPF authenticates the server that connected, so it breaks the moment a message is relayed — a mailing list, a university alias, a forwarded mailbox. A DKIM signature travels with the message and survives the hop. The same section warns that with -all, a message that would have passed DMARC on an aligned DKIM signature can be rejected on the SPF failure alone.

So the order is: get DKIM signing first, confirm it with the DKIM record checker, and only then tighten SPF to -all. Tightening SPF before DKIM works is how you lose forwarded mail. Your DMARC policy and alignment mode is the third piece, and it is what actually decides what happens to a failure.

Key fact: RFC 9989 §7.4 also advises that domains whose users post to mailing lists “SHOULD NOT publish” p=reject at all, because list software routinely modifies messages in ways that invalidate signatures. -all with p=reject is right for a transactional or marketing domain. It is not a universal goal for every domain.

Publishing the record

  1. Open your DNS panel at whoever answers for the domain — your registrar, your host, or a DNS provider like Cloudflare. It is wherever you would change an A record, not your email platform.
  2. Add a new record of type TXT. Do not edit an existing SPF record into a second one — two v=spf1 records at the same name is a permanent error.
  3. Set the host to the domain itself. Most panels want @ or an empty field; a few want the full domain typed out.
  4. Paste the record exactly as built, starting v=spf1. If it is long enough to need several strings, see below.
  5. Set the TTL — 3600 seconds is a reasonable resting value, but lower it before a planned change, as explained below.
  6. Save, wait out the TTL, then read it back and confirm a receiver agrees with you.

The record goes at the domain itself, not at a subdomain of it and not at a special name. Most DNS panels want @ or an empty host field to mean “the domain itself”; some want the full domain typed out. If you are unsure which, publish it and then read it back with the DNS lookup tool — if it appears at example.com rather than @.example.com, you got it right.

Lower the TTL before you change anything

The TTL on the record controls how long resolvers keep the old answer. A day before a planned change, drop it to something short — 300 seconds is a common choice. Make the change, confirm it, then put the TTL back up. Without that, a mistake stays cached for as long as the old TTL said.

There is a second cache that catches people out, and it works in the opposite direction. If you check a name before publishing anything there, the resolver caches the fact that nothing exists. RFC 2308 sets how long that negative answer is kept, from your zone’s SOA record. So a record you definitely published can still read as missing, and waiting is the fix rather than editing. The often-repeated “wait 24 to 48 hours” is folklore — check the actual TTL instead.

When the record is too long for one string

A single DNS character-string cannot exceed 255 octets. Longer records are published as several strings that the resolver joins back together — RFC 7208 §3.3 says they are concatenated “without adding spaces”. This looks alarming in a DNS panel and is completely normal. The builder shows you the exact split when your record needs one.

Two things go wrong here. Some panels split the record for you when you paste it, and some expect you to enter each quoted string yourself — so always read the saved value back. And splitting in the wrong place, mid-term, produces a record that parses into nonsense while looking fine at a glance.

There is also an upper bound on the whole answer. RFC 7208 §3.4 asks that a query for your record fit within 512 octets, and gives a practical guideline of 450 octets for everything published at that name — which includes your verification strings and every other TXT record you have there, not just SPF. Records too long for one UDP packet, the RFC warns, “could be silently ignored”.

What to do when you are over ten lookups

The builder shows which term is costing what, so start by reading that table rather than guessing. In most records one or two includes account for most of the bill. Four options, roughly in order of how much trouble they cause later.

1. Remove what you are not using

This is the one that works most often and costs nothing. Records accumulate: a trial of a marketing tool three years ago, a helpdesk you migrated away from, an invoicing service that was replaced. Each of those is still costing lookups, and a dead one is costing you a void lookup as well. If a service no longer sends mail for you, delete its include.

2. Replace an include with the addresses behind it — carefully

If a provider publishes a small, stable set of addresses, listing them as ip4: terms costs nothing instead of one lookup plus their chain. This is what “flattening” means, and it is worth being precise about, because the advice you will read elsewhere is louder than the evidence behind it.

The word “flattening” does not appear in RFC 7208 at all, nor in M3AAWG’s best-practice documents, nor in Google’s SPF documentation. Microsoft is the only major authority that documents it, and its guidance is conditional rather than an endorsement:

  • Flatten vendors with “stable, documented IP address ranges”.
  • Do not flatten Microsoft 365. Microsoft’s own wording: its “sending infrastructure uses dynamic IP addresses that change frequently”. The same caution applies to any cloud service that renumbers.
  • If you do flatten, document what you replaced and “review and update the flattened entries at least quarterly”.

In other words, a flattened record is correct on the day you publish it and silently wrong afterwards. It converts a lookup problem into a maintenance problem. That is sometimes the right trade — but it is a trade, and the services most people want to flatten are exactly the ones Microsoft says not to.

3. Move a heavy sender to its own subdomain

Subdomains do not inherit the parent’s SPF record — Microsoft states it plainly: “the SPF TXT record for contoso.com doesn’t cover marketing.contoso.com; marketing.contoso.com needs its own SPF TXT record.” That sounds like extra work, and it is also a way out. Send your marketing mail from news.example.com, give that subdomain its own record containing only the marketing provider, and the two records have separate ten-lookup budgets.

This has a second benefit worth more than the lookups: a deliverability problem on the marketing stream stops dragging down the domain your invoices and password resets come from.

4. What not to do

You will find advice that SPF macros are “a better alternative” to flattening. No standards body or mailbox provider says so. RFC 7208 §7.3 cautions the other way — macros “severely limit the ability of implementations to cache results” — and the exists: mechanism they rely on is itself one of the ten counted terms. Macros can collapse many includes into one lookup, which is genuinely useful, but they do not escape the limit and no authority recommends them for this.

And do not publish a second SPF record to hold the overflow. Two v=spf1 records at one name is a permanent error, not a continuation.

Domains and subdomains that send no mail

Every domain you own and never send from should still publish an SPF record, and it is the shortest one there is:

v=spf1 -all

That authorises nothing at all, which is the point. RFC 7208 §10.1.2 calls publishing it “a well-established best practice”, and M3AAWG’s parked domains guidance calls it a “naked -all”. A domain with no SPF record is an open invitation: anyone can send mail claiming to be from it, and when recipients report that mail as spam the complaint attaches to your name. To build it here, leave every field empty and choose hard fail.

Worth doing on the defensive registrations nobody uses, and the old domain you redirect to the new one.

Subdomains need their own record

A subdomain does not inherit the parent’s SPF record. Microsoft puts it plainly: “the SPF TXT record for contoso.com doesn’t cover marketing.contoso.com; marketing.contoso.com needs its own SPF TXT record.” So news.example.com is unprotected even when example.com is locked down, and a spoofer can use it.

That cuts two ways, and the second is useful. Any subdomain that sends mail needs its own record here — but because each name carries its own ten-lookup budget, moving a heavy sender onto a subdomain is a legitimate way out of the limit, as section six describes. For subdomains that never send, publish v=spf1 -all on each, or a wildcard record covering the tree if your DNS provider allows it. RFC 7208 §3.5 discourages wildcards generally and notes the declaration “MUST be repeated for any host that has any RR records at all”, so a wildcard is a convenience, not a substitute for records on the names you actually use.

One documented disagreement: Google’s guidance for non-sending domains recommends ~all rather than -all, where RFC 7208, M3AAWG and Microsoft all say -all. We are flagging it rather than picking a winner quietly: if a domain genuinely sends no mail, there is nothing legitimate for a hard fail to break.

Spoofing your unused domains is a reputation problem before it is a security problem, and reputation is what receivers actually weigh — our guide to how receivers build a reputation score covers the signals, and what puts a domain on an email blacklist explains where it ends up when it goes wrong.

Mistakes this builder will not make for you

Every generator we were able to inspect accepts whatever you type and writes it into the record. That is how a typo becomes a DNS entry that fails silently for months. These are refused instead.

  1. An include that publishes no SPF record. Each hostname is resolved before it is used. If nothing is there, it is left out and you are told — because including it would authorise nothing and burn a void lookup.
  2. An address that is not an address. A transposed digit, a prefix of /33, an IPv6 prefix over /128, a hostname pasted into the IP box. All refused with the reason.
  3. The same sender twice. A duplicate include costs its lookups twice and authorises nothing extra. Duplicates are removed and reported.
  4. A ptr term. RFC 7208 §5.5 is titled, literally, “ptr (do not use)” and says the mechanism “SHOULD NOT be published”. It is slow, unreliable under DNS errors, and loads the .arpa nameservers. Verifiers must still support it, so an existing one keeps working — but this builder will not write a new one.
  5. redirect= and all together. RFC 7208 §6.1: a redirect “MUST be ignored if there is an ‘all’ mechanism anywhere in the record”. Choose redirect and the all term is dropped, with the reason shown.
  6. An include chain that loops. If a chain leads back to itself, you are told. The specification defines no loop detection, so a receiver simply keeps resolving until it trips the ten-term limit and permerrors.
  7. +all. It authorises the entire internet to send as your domain. There is no legitimate use, so it is not offered.

One mistake no tool can catch for you: forgetting a sender. SPF only helps if the list is complete, and the services people forget are the quiet ones — the helpdesk that emails ticket replies, the CRM that sends from a salesperson’s address, the monitoring system that pages you at 3am. If mail from one of those starts going missing after you tighten to -all, that is the cause. The fastest way to find them is to read the authentication results on a message that actually arrived, which the email header analyzer lays out hop by hop.

And if mail is still being refused after SPF, DKIM and DMARC all pass, the problem has moved from authentication to reputation — why an address gets blocked in the first place is the next thing to read.

Frequently asked questions about SPF records

How many DNS lookups does my SPF record use?

Count every include:, a, mx, ptr, exists and redirect= term, then count the same terms inside every record those pull in. ip4:, ip6: and all cost nothing. You cannot work this out from your own record alone, because most of the cost is inside your providers’ records — which is why the builder above resolves each chain rather than asking you to guess.

Why does this tool say Google costs one lookup when other sites say four?

Because it resolved _spf.google.com instead of reading a stored table. The number four is a fossil from when that record nested three include:_netblocks terms; it now lists IP ranges directly. The practical lesson is broader than Google: a provider can change their record at any time and never tell you. Re-run the builder after any provider migration, and treat any lookup cost you read on another site as a guess about the past.

What happens if my SPF record goes over 10 lookups?

RFC 7208 §4.6.4 requires receivers to return permerror, and that is the whole record failing, not just the term that crossed the line. What you actually observe is confusing: mail that worked for years starts landing in spam, and it happens to all your senders at once, including servers you listed correctly by IP. If deliverability fell off a cliff with no DNS change of your own, a provider adding an include to their record is a prime suspect.

What is a void lookup, and why does it matter?

It is a term whose DNS query returns nothing — an empty answer, or a name that no longer exists. RFC 7208 §4.6.4 says implementations “SHOULD limit void lookups to two”, so a record can be comfortably inside the ten and still fail. To find which term is responsible, build your record above: any include that resolves to nothing is refused and named, which is usually a service you stopped paying for whose record was deleted.

Should I use -all or ~all?

~all while you are still finding your sending sources, -all once the list is complete. But sequence matters more than the choice: RFC 9989 §7.4 states that a domain publishing p=reject “MUST NOT rely solely on SPF … and MUST apply valid DKIM signatures”. Get DKIM signing first, because -all rejects forwarded mail that an aligned DKIM signature would have rescued.

Can I have two SPF records on one domain?

No — two v=spf1 records at one name is a permanent error, not a merge and not a fallback. This is the most common way a working setup breaks: somebody adds a new provider by creating a second TXT record instead of editing the existing one. To fix it, combine every term from both into one record and delete the other. Paste both into the builder above and it will deduplicate them and tell you what the combined record costs.

Do subdomains use my main domain’s SPF record?

No. Each subdomain that sends mail needs its own record — Microsoft states it plainly: “the SPF TXT record for contoso.com doesn’t cover marketing.contoso.com”. Two consequences worth knowing. A subdomain you never send from should get its own v=spf1 -all, or a wildcard record covering the tree, because otherwise it is spoofable even when the parent is locked down. And a subdomain is a legitimate escape from the ten-lookup limit, since each name carries its own budget.

What record should I use for a domain that sends no email?

v=spf1 -all and nothing else. To build it here, leave every field empty and choose hard fail. Worth applying to more names than people expect: defensively registered domains, an old domain you now redirect, and any subdomain that exists for a website rather than for mail. One caveat if you also publish DMARC — a naked -all stops nothing on its own unless a policy tells receivers what to do with the failure.

Should I flatten my SPF record?

Only for vendors whose address ranges are genuinely stable and documented, and never for Microsoft 365, whose sending infrastructure “uses dynamic IP addresses that change frequently”. The hard part is judging “stable”: if a vendor publishes its ranges on a versioned page or in a machine-readable file, that is a reasonable sign; if the only source is a support article, assume it will change without notice. Whatever you flatten, you have signed up to re-check it — Microsoft says quarterly.

Are SPF macros a better alternative to flattening?

They are a different thing, not a better one, and no standards body or mailbox provider recommends them for this. What macros genuinely do well is per-connection authorisation — an exists: term built from the connecting IP lets one lookup stand in for a list that would otherwise need many. That is useful at real scale. It does not get you out of the limit, because exists: is itself one of the ten counted terms.

Why does the builder refuse to add ptr?

RFC 7208 §5.5 is titled, literally, “ptr (do not use)”. If you already have one, you do not need to panic: verifiers must still support it, so it keeps working. Remove it at your next edit, and replace whatever it was authorising with the actual IP addresses of those hosts — which costs zero lookups instead of one, and does not depend on the reverse DNS of the connecting machine being correct.

What is redirect= and when should I use it?

It hands evaluation entirely to another domain’s record, which suits a group of domains sharing one sending policy. Two rules catch people out: RFC 7208 §6.1 says a redirect “MUST be ignored if there is an ‘all’ mechanism anywhere in the record”, so the two cannot be combined; and if the target publishes no SPF record the result is permerror, not a quiet “none”. For a single domain, include: is almost always the better choice.

How long does an SPF change take to work?

There is no fixed answer, and the “wait 24 to 48 hours” advice is folklore. It depends on the TTL of the record, and on negative caching if you happened to check the name before publishing — RFC 2308 derives how long a cached “this does not exist” answer survives from your zone’s SOA. The practical routine: lower the TTL a day ahead, make the change, verify, then raise it again.

Do I still need DKIM and DMARC if my SPF record is correct?

Yes, and the order is worth getting right: SPF, then DKIM, then DMARC policy. SPF authenticates the connecting server, so it breaks the moment a message is forwarded; a DKIM signature travels with the message. That is why RFC 9989 §7.4 makes DKIM a requirement rather than a suggestion for any domain at p=reject. Publishing an enforcing DMARC policy before DKIM is signing every one of your streams is how legitimate mail starts disappearing.

Can I share the record this tool built?

Yes — your whole build lives in the address bar, so sending the link passes the record, the lookup count and every warning to whoever manages your DNS. The count is recalculated live when they open it rather than stored, so if a provider changed their record in between, the link shows the new number instead of a stale one. Nothing you enter is kept on our side.

Related email authentication tools

Build the record here, then confirm it is doing its job. SPF is one of three checks a receiver runs, and it is the one that breaks on forwarding.

A record that builds clean can still fail live

Publish it, wait for the TTL, then read it back from DNS. The checker counts the chain again from what you actually published and can simulate whether a given sending IP would pass.

Last updated 22 September 2026 · Lookup costs resolved live from public DNS on every build; rules from RFC 7208