Diagnostic suite · live

SPF explained — writing a strict record without breaking mail

How SPF works, the 10-lookup trap, and a production-safe rollout template.

Isometric illustration of an SPF shield with a passing envelope and rejected sender tokens

SPF explained — writing a strict record without breaking mail

How SPF works, the 10-lookup trap, and a production-safe rollout template.

10 min read

SPF — Sender Policy Framework — is a DNS TXT record that lists the IP addresses and hostnames authorized to send email using your domain in the MAIL FROM envelope. Receivers use it to decide whether an inbound message is legitimate. Get it wrong and you either let spammers impersonate your brand (too permissive) or bounce your own transactional email at Christmas (too strict). This guide walks through what SPF actually authenticates, the RFC-defined lookup limit that silently breaks a huge percentage of published records, and the safe rollout path from monitoring to enforcement.

What SPF is (and what it is not)

SPF authenticates the envelope sender — the address a sending server declares during the SMTP MAIL FROM exchange. This address is invisible to end users; the address your users see is the From: header, which is a totally separate field that SPF does not check at all. A spammer can pass SPF for evil.com while sending mail with From: ceo@yourbank.com, and SPF will happily return "pass." Closing that gap is DMARC's job. Read our DMARC guide next.

What SPF is good at: proving that a given IP is authorized to send envelope-signed mail on your behalf. That's the foundation everything else builds on.

The anatomy of an SPF record

example.com.  IN  TXT  "v=spf1 include:_spf.google.com include:mailgun.org ip4:203.0.113.10 -all"

Reading left to right:

  • v=spf1 — the version tag. Always this. Records without it are ignored.
  • include:_spf.google.com — delegate authorization to another domain's SPF record. Every ESP publishes one. This is how you say "Google Workspace is allowed to send as me."
  • ip4:203.0.113.10 — explicit IPv4 authorization. Use for on-prem MTAs, marketing servers, transactional relays you run yourself.
  • -all — the fall-through policy. Anything not matched above fails hard: receivers should reject the message.

Other qualifiers you'll see:

  • + pass (implicit default; you rarely write this).
  • - hard fail.
  • ~ soft fail — accept but mark suspicious. Useful during rollout.
  • ? neutral — receiver treats as if no policy exists. Effectively useless.

The 10-lookup trap that quietly kills SPF

RFC 7208 §4.6.4 imposes a hard limit: an SPF evaluation can perform at most 10 DNS lookups. Every include:, a, mx, ptr, and exists mechanism counts, and lookups inside included records count against your total too. Exceed the limit and receivers must return permerror, which is functionally identical to having no SPF at all.

This limit is trivially easy to hit. A typical growing company publishes something like:

v=spf1 include:_spf.google.com include:mailgun.org include:mail.zendesk.com include:_spf.salesforce.com include:helpscoutemail.com include:_spf.intercom.io -all

Google alone recursively includes three sub-records that together spend four lookups. Add Mailgun (2), Zendesk (2), Salesforce (3), Help Scout (2), Intercom (2)... you're at 15 lookups and every receiver is dropping your SPF on the floor. You will not see a bounce message. Your DMARC reports will start showing SPF failures for every legitimate sender, and you'll wonder why deliverability tanked. Use our SPF Checker to count your record's real recursive lookup total.

Fixing the lookup count

  1. Remove what you don't use. Most companies have SPF includes for ESPs they piloted years ago. Audit the list against your actual senders.
  2. Use subdomains. Send transactional mail from t.yourdomain.com, marketing from m.yourdomain.com. Each subdomain gets its own SPF, its own 10-lookup budget, and its own DKIM. This is the cleanest long-term architecture.
  3. SPF flattening. Replace include: mechanisms with the ip4: addresses they resolve to. Works today, but the ESP may change IPs without warning — you need monitoring to catch drift.

Common mistakes to avoid

  • Two SPF records. Publishing two SPF TXT records on the same domain is a permerror. Merge into one.
  • Wrong record type. SPF lives in a TXT record. The old dedicated SPF record type (RRtype 99) was deprecated by RFC 7208 §3.1.
  • Missing subdomains. SPF does not inherit. If you send from notifications.yourdomain.com, that subdomain needs its own SPF record.
  • Trailing wildcard. Ending in +all allows anyone in the world to send as you. It happens more than you'd think.
  • Testing only from your desk. Deliverability varies by receiver. Enable DMARC aggregate reporting and let Google, Microsoft, Yahoo tell you the real story.

The safe rollout playbook

  1. Inventory every sender. Transactional, marketing, CRM, helpdesk, monitoring, internal, contractor, that one intern's Zapier — all of them.
  2. Publish SPF with ~all (soft fail). This is monitoring mode.
  3. Publish DMARC with p=none and an rua= reporting address. Now you get daily reports showing every source and whether SPF/DKIM aligned.
  4. Wait two weeks. Fix any missing senders you spot in reports.
  5. Switch SPF to -all and DMARC to p=quarantine. Watch reports for another two weeks.
  6. Move DMARC to p=reject. You now have production-grade email authentication.

Verifying with dig

# Fetch the SPF record
dig +short TXT yourdomain.com | grep spf1

# Trace an include: to see what IPs it authorizes
dig +short TXT _spf.google.com

Then paste the record into our SPF Checker for a full lookup-count audit and mechanism-by-mechanism breakdown.

Summary

SPF is small, old, and quietly load-bearing for your entire email program. It costs nothing to publish, silently breaks the moment you exceed 10 lookups, and forms one of the two pillars — with DKIM — that DMARC needs to work at all. Publish it, audit it every quarter, and treat any new ESP integration as a chance to check your lookup budget before it bites you.

Related tools: SPF Checker · DMARC Checker · DMARC Generator · DKIM Checker

Frequently asked questions

-all is a hard fail — mail from unauthorized IPs will typically be rejected by receivers. ~all is a soft fail — receivers accept the mail but mark it as suspicious. Start with ~all during rollout, then switch to -all once monitoring shows every legitimate sender is authorized.