Guide

SPF Records. The Complete Guide

What SPF is, why mailbox providers care, and how to author a record that doesn't break in six months.

12 min read·Updated May 25, 2026
TL;DR
SPF tells the world which servers are allowed to send mail "from" your domain. The two things that quietly break it: too many DNS lookups (the hard cap is 10) and a missing or wrong all mechanism. Get those right, end with -all once DMARC reports are clean, and you've done 90% of the job.

What is SPF?

SPF (Sender Policy Framework) is a DNS-based mechanism that lets you publish, in a single TXT record, the list of servers permitted to send email "from" your domain. When a receiving mail server gets a message claiming to be from you@example.com, it looks up example.com's SPF record and asks: "is the IP that just connected actually on this list?" If yes, SPF passes. If no, SPF fails, and depending on the receiver's policy and your DMARC record the mail gets marked as spam, quarantined, or rejected outright.

It's old (the standard predates 2006), it's blunt, and on its own it doesn't stop phishing. But every major mailbox provider. Gmail, Outlook, Yahoo, Apple iCloud, still requires it as part of the authentication baseline. Since Gmail and Yahoo's 2024 bulk-sender rules took effect, sending without SPF essentially guarantees the spam folder.

Why it matters

Three concrete things SPF does for you:

  • Deliverability: Mail without a passing SPF check is heavily penalized. A correctly aligned SPF can be the difference between inbox and spam folder for routine transactional email.
  • Anti-spoofing (limited): SPF makes it harder, though not impossible, for attackers to impersonate your envelope sender. The visible From header is a different battle (that's DMARC's job).
  • A precondition for DMARC: DMARC enforcement requires either SPF or DKIM to pass and align with the From domain. No SPF means you're leaning entirely on DKIM, which is fine in theory but doubles your risk if DKIM ever breaks.

How SPF works under the hood

A receiving server sees an incoming SMTP connection from IP 198.51.100.42 claiming the envelope sender bounce@example.com. It does:

  1. Query example.com for TXT records.
  2. Find the one starting with v=spf1.
  3. Evaluate each mechanism left-to-right against the connecting IP.
  4. Return one of: pass, fail, softfail, neutral, none, permerror, temperror.

That result is then handed to whatever spam scoring + DMARC logic the receiver runs.

Anatomy of an SPF record

v=spf1 include:_spf.google.com include:sendgrid.net ip4:198.51.100.0/24 ~all

The version tag

v=spf1 always comes first. There is no v=spf2. If you see "SPF version 2" mentioned anywhere, it's a misnomer, what people mean is "use both SPF and Sender ID", and Sender ID is effectively dead.

Mechanisms

The clauses that match incoming IPs:

  • ip4: / ip6:, explicit IP allowlist (no DNS lookup cost).
  • a, match the domain's A records (costs one lookup).
  • mx, match the domain's MX hosts' IPs (one lookup, plus one per MX).
  • include:, defer to another domain's SPF record (one lookup, plus whatever that record costs recursively).
  • exists: / ptr:, rarely needed. ptr is officially deprecated; don't use it.
  • all, the catch-all at the end, must be last.

Qualifiers

Each mechanism can be prefixed with one of:

  • +, pass (default if omitted)
  • -, fail
  • ~, softfail
  • ?, neutral

You almost only ever see qualifiers on the final all mechanism. -all means "anything that didn't match above is unauthorized, reject it." ~all means "treat it as suspicious but you decide." +all means "everyone is authorized" and is a serious security mistake.

Critical
If you see +all anywhere in your SPF record, fix it today. It tells the entire internet that any server is allowed to send as your domain. Attackers actively scan for this.

The 10-lookup limit (where most records die)

RFC 7208 caps an SPF evaluation at 10 DNS lookups. Each include, a, mx, ptr, exists, and redirect counts as one. ip4 and ip6 are free.

The trap: include is recursive. include:_spf.google.com looks like one lookup, but _spf.google.com itself contains four more includes. Google alone consumes about 4 lookups depending on the day. Add SendGrid (3), Mailgun (3), HubSpot (5), and you're permerror.

When you hit the limit, receivers return permerror, which most treat as no SPF at all. Months of carefully composed records evaporate.

The two real fixes:

  • Flatten: replace include: mechanisms with the underlying ip4: ranges. Lots of free tools and paid services (EasyDMARC, Valimail, Scott Helme's tools) automate this. The downside is you have to re-flatten when a provider changes IPs.
  • Trim: remove services you don't actually use anymore. A surprising fraction of 11-lookup records contain a Mailchimp or Mandrill include from a campaign that ended three years ago.

The mistakes we see every single day

  1. Two v=spf1 records on the same domain. Often introduced when a new service is added without checking. Result: undefined. Fix: merge into one record.
  2. No all mechanism at all. The record passes for listed senders but doesn't say what to do about anyone else. Receivers treat this as neutral, which means no real protection. Fix: add ~all or -all.
  3. ?all "neutral". Almost always a mistake. It explicitly tells receivers "I have no opinion." If you've gone to the trouble of authoring SPF, have an opinion.
  4. Exceeding 10 lookups. The silent killer described above.
  5. Macros nobody understands. SPF supports macros (%{d}, %{i}, etc.). They're powerful and almost universally misused. Avoid unless you genuinely need them.
  6. Treating SPF as anti-phishing on its own. SPF authenticates the envelope-from. Phishers spoof the visible From header. You need DMARC for that.

How to deploy SPF the right way

  1. List every service that sends mail "from" your domain: Google Workspace, your transactional provider (SendGrid/Postmark/Resend), your marketing tool, your CRM, your support desk, anything else.
  2. Find each provider's recommended include: string. They publish it.
  3. Compose a single record: v=spf1 include:provider-a include:provider-b ~all. Start with ~all, not -all.
  4. Publish it as a TXT record at the root of your domain. Most DNS providers handle quoting automatically; if you have to quote manually, the whole record goes in one string (or use the 255-character splitting rules carefully).
  5. Use our SPF checker to verify lookup count is under 10 and the record parses cleanly.
  6. Enable DMARC with p=none; rua=mailto:dmarc-reports@yourdomain.com and watch reports for two weeks.
  7. Once reports show 100% authentication from your real senders, flip ~all to -all.

Monitoring SPF going forward

SPF records rot. New tools get added without updating the record. Providers change their include: chains and quietly push you over the 10-lookup limit. Someone "cleans up DNS" and deletes a critical entry.

You need a system that:

  • Re-checks your SPF on a schedule (hourly is overkill for SPF specifically, but it's free).
  • Alerts when the record text changes, not just when it fails. A silent change today is a deliverability incident next week.
  • Tracks lookup count drift over time, so you see the slow climb from 6 to 8 to 10 before it hits 11.

This is exactly what DomainsDoc does. You add your domain, we check it hourly, and we ping you the moment your SPF record changes, exceeds 10 lookups, or starts failing for any reason. Plus DKIM, DMARC, MX, blacklists, SSL, WHOIS, and HTTP, together, since they share root causes.

Frequently asked questions

What is an SPF record in plain English?
An SPF record is a single TXT record on your domain that lists the servers and services allowed to send email "from" your domain. Receiving mail servers fetch your SPF record and use it to decide whether incoming mail claiming to be from you is legitimate.
Can I have more than one SPF record?
No. RFC 7208 explicitly forbids multiple v=spf1 records on the same domain. If you have two, receivers may pick one at random or treat the configuration as a permerror, both bad outcomes. Merge them into a single record.
What is the SPF 10-lookup limit?
SPF restricts you to a maximum of 10 DNS lookups per evaluation. Each include:, a, mx, ptr, exists, and redirect mechanism counts as one lookup. Exceed it and your record returns permerror, equivalent to having no SPF at all for many receivers.
Should I use ~all or -all at the end of my SPF record?
-all (hardfail) tells receivers to reject mail that does not match. ~all (softfail) suggests treating it as suspicious but accepting it. For most domains -all is the goal, but only after you have verified DMARC reports show every legitimate sender is covered.
How do I check if my SPF record is valid?
Use the SPF Record Checker tool: it pulls your TXT record, parses each mechanism, counts your DNS lookups, and flags the most common authoring mistakes. Or run `dig +short example.com TXT` and look for the line starting v=spf1.
My SPF passes but DMARC fails. Why?
DMARC requires identifier alignment: the domain in your envelope-from (Return-Path) must match (or be a subdomain of) the domain in your visible From header. SPF can pass while DMARC fails if your sending service uses its own return-path domain. Fix: enable a custom return-path on the sending service.
Try it now
Check any SPF record

Free, instant, no signup. Parses every mechanism, counts your lookups, flags mistakes.

Open tool
Stop reading. Start monitoring.

Continuous SPF, DKIM, DMARC, blacklist, SSL, and uptime checks. Alerts the moment something breaks.

Start free
Keep reading