Sooner or later, setting up email for a domain hands you the same homework: "publish an SPF record." It sounds like a chore for a specialist, but an SPF record is just one line of plain text that you paste into your DNS. The catch is that the line has to be exactly right. Get a piece wrong and the failure is quiet — no error message, just mail that drifts into spam folders or gets refused outright, weeks after you thought you were done.

This is a build guide. We'll go from "I have no SPF record" to a correct one you can publish today, step by step, and flag the two mistakes that account for most broken records. If you want the deeper background on why SPF exists before you build one, our SPF records explainer covers the theory; here we're focused on assembling the record itself.

What an SPF record is, in one paragraph#

SPF — Sender Policy Framework — is a public list of the servers allowed to send email for your domain. You publish it as a single TXT record in DNS. When a receiving mail server gets a message claiming to be from you@example.com, it looks up that TXT record and checks whether the server that actually delivered the message is on the list. If it is, the message passes SPF. If it isn't, the receiver applies whatever policy your record specifies. That's the whole idea: prove that the sending server is one you authorized.

SPF is a TXT record like any other in your zone — if the record-type vocabulary is new to you, our guide to DNS record types places it in context. Here's a complete, valid example for a domain that sends through Google Workspace plus a marketing platform:

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

Every SPF record is built from those same kinds of pieces. Let's take them in the order you should think about them.

Step 1 — List every service that sends as your domain#

This is the step people skip, and skipping it is the root cause of most SPF problems. Before you write anything, make an honest inventory of everything that sends email using your domain in the From address. That includes the obvious mailbox provider — Google Workspace, Microsoft 365 — but also the long tail that's easy to forget:

  • Your transactional and marketing platforms — SendGrid, Mailchimp, Amazon SES, Postmark, and the like.
  • Your CRM, helpdesk, invoicing, and e-commerce tools, each of which may send on your behalf.
  • Any server or app you run that sends mail directly from its own IP address.

If a sender is missing from this list, its mail will fail SPF once you publish an enforcing record. The goal is a complete roster before you build, not a record you keep patching every time something breaks.

Step 2 — Turn each sender into a mechanism#

An SPF record authorizes senders through small instructions called mechanisms. You only need three of them in practice:

  • include: — hands the check off to another domain's SPF record. This is how nearly every hosted service is authorized: Google publishes _spf.google.com, SendGrid publishes sendgrid.net, and you simply include theirs. You don't track their IP addresses; they do.
  • ip4: and ip6: — authorize a specific address or range you control directly, like a mail server in your own data center. You can list a single address (ip4:203.0.113.5) or a whole block in CIDR notation (ip4:203.0.113.0/24).
  • a and mx — authorize whatever IPs your domain's A or MX records point to. Handy when your sending host and your published records are the same machine, but use them sparingly: each one costs a DNS lookup, which matters in a moment.

For most teams the record is almost entirely include: statements — one per hosted service — with maybe one ip4: for a server they run themselves. Every record starts with the version tag v=spf1, and that tag must come first.

Step 3 — Choose your enforcement: ~all vs -all#

The record ends with an all mechanism, and its qualifier is the single most consequential character in the whole line. It tells receivers what to do with mail from a server that isn't on your list:

  • ~all (softfail) — "this probably isn't authorized, but accept it and mark it suspicious." Unlisted mail usually still arrives, often in spam.
  • -all (hardfail) — "this is not authorized; reject it." Stricter, and the right end state, but unforgiving of any sender you forgot in Step 1.
  • ?all (neutral) — "no opinion." This authorizes nothing meaningfully and is rarely what you want.

The safe path is to publish with ~all first. Watch your mail flow for a week or two, confirm every legitimate sender is passing, then tighten to -all once you trust your list. Moving straight to -all on day one is how a forgotten invoicing tool starts bouncing — softfail buys you a margin for error while you verify.

Step 4 — Mind the 10-lookup limit#

Here's the gotcha that breaks records which otherwise look perfect. SPF caps the number of DNS lookups a single evaluation may trigger at ten. Each include:, a, mx, and a few related mechanisms counts against that budget — and an include can pull in another record with its own includes, so the count grows faster than the visible line suggests. One include:_spf.google.com alone resolves into several nested lookups.

Exceed ten and SPF doesn't just ignore the extras — it returns a permerror, and many receivers treat that as an outright failure. The whole record stops working. So keep the includes lean: drop services you no longer use, prefer a single platform over three overlapping ones, and avoid stacking a/mx mechanisms you don't strictly need. If you're brushing against the limit, that's a signal to consolidate senders, not to cram more in.

Step 5 — Publish it (and publish only one)#

The finished record goes into DNS as a TXT record on the root of your domain — the host field is @ or the bare domain name, not a subdomain and not spf.example.com. The value is the full string, starting with v=spf1.

One rule trips people up more than any other: a domain may have exactly one SPF record. If you publish two TXT records that both start with v=spf1 — say, one left over from an old provider and one you just added — SPF treats that as a permerror and both fail. When you add a new sender, you edit the existing record to add the include; you never publish a second one. After saving, the change has to propagate, which can take anywhere from minutes to a few hours depending on your DNS propagation and TTL.

Try it

Build your SPF record from a form

Our SPF record generator walks the steps above as a guided form — pick Google Workspace, Microsoft 365, SendGrid, or Amazon SES presets, add your own includes and IP ranges, and choose ~all or -all. It assembles a valid record with a live preview and copy button, entirely in your browser. Nothing you type is sent anywhere.

Open the SPF Generator →

Step 6 — Verify what you published#

Generating a record and pasting it in isn't the finish line — confirm DNS is actually serving what you intended. Run the published domain through our SPF checker: it fetches the live record, parses every mechanism, walks the full include chain, and counts the DNS lookups against the limit of ten. That's the moment a hidden second record, a typo in an include, or a lookup count of eleven shows up — while it's a quick fix, not a deliverability incident.

It's worth re-checking on a schedule, too, not just once. SPF records drift: a new tool gets added, an old include points at a service you've since dropped, a vendor changes their sending infrastructure. A record that passed in January can quietly slip over the lookup limit by June.

SPF is one leg of three#

A passing SPF record is necessary, but on its own it's not the full story of email authentication. SPF checks the sending server; DKIM cryptographically signs the message so receivers can confirm it wasn't altered in transit; and DMARC ties the two together and tells receivers what to do when a message fails. Gmail and Yahoo now require DMARC for bulk senders, and DMARC needs at least one of SPF or DKIM aligned and passing to do its job — which is exactly why getting SPF right is usually the first move.

So build SPF carefully, publish it with ~all, verify it, tighten to -all when you trust your list — then do the same for DKIM and DMARC. Our DMARC explainer picks up where this leaves off, and a single domain health report will show all three side by side once they're live.

An SPF record is one line of text. The discipline is in the inventory behind it — list every sender first, and the line writes itself.