Skip to content
🚀 10 tools live, free forever — the toolbox keeps growing
Home›Blog›Why Your SPF Record Keeps Failing (and How to Fix It)
Guides

Why Your SPF Record Keeps Failing (and How to Fix It)

How to read your own SPF record line by line, why the ten-lookup limit breaks it silently, why forwarded mail fails even when the record is correct, and how to fix a record that keeps returning fail or softfail.

✍ By the Founder & CEO, Team BuildToolForge🗓 2026-10-16⏱ 11 min
spfemaildnsemail deliverabilitydmarc
Email Security Guide2026

SPF Records
Made Simple

How to read your SPF record

Ten-lookup limit · Mechanisms · Qualifiers

dig · TXT
$ dig example.com TXT +short
v=spf1include:_spf.google.com ~all
lookups4 of 10
forwardbreaks SPF by design
✓ under the limit · ~all is a soft fail
Mechanisms
include
Nested
a
Host
mx
Mail host
ip4
Address
ip6
Address
all
Catch-all
Stay under ten lookupsCorrect qualifierSurvive forwardingAlign with DMARC

What SPF actually checks

SPF — Sender Policy Framework — is a TXT record on your domain that lists which servers are allowed to send mail for you. A receiving server looks up that record, compares it against the IP address that just connected, and decides whether the connection is authorised.

Two details about what it compares explain most SPF confusion:

  • SPF checks the envelope sender, not the From: address your recipient sees. The envelope sender (the MAIL FROM in the SMTP conversation, also called the return path) is invisible in the mail client. A message can pass SPF while displaying a completely different, forged From: address — which is why SPF on its own does not stop spoofing.
  • SPF checks the connecting IP address, nothing else. It does not inspect the message, the headers or the content. It is one question: was this IP allowed to connect on your behalf?

So an SPF failure almost never means your record is malformed. It usually means mail left from somewhere the record does not list, or that the record could not be fully evaluated. Those are different problems with different fixes, and the rest of this guide separates them.

How to read your own SPF record

An SPF record is a single line of TXT, and it is readable once you know the four parts.

Mechanisms: who is allowed

Each term adds permitted senders. ip4: and ip6: list addresses or ranges directly. a authorises whatever your domain's A record points at. mx authorises your own mail servers. include: is the one that matters most in practice: it pulls in another domain's entire SPF record, which is how you authorise Google, Microsoft or a bulk sender without knowing their addresses.

include: is a delegation, not a copy. The other party can change their list at any time and your record follows along — which is the point, and also the reason your record can break without you touching it.

Qualifiers: what happens on a match

Each mechanism can carry a prefix. + is pass and is the default, so a bare mx means +mx. - is a hard fail: reject. ~ is a soft fail: accept, but mark it. ? is neutral: no opinion, which is effectively no policy at all.

The all at the end

The last term is almost always an all mechanism, and it decides what happens to every sender the record did not list. -all says reject everything else. ~all says accept but flag it. +all authorises the entire internet and is always a mistake.

Start at ~all while you are still finding out who legitimately sends for you, then tighten to -all once your DMARC reports are clean. Going straight to -all without that evidence is how a forgotten invoicing system or help desk stops reaching anyone.

Exactly one record, no exceptions

A domain may publish one SPF record. Two TXT records both starting v=spf1 is a permerror, and a permerror means the check cannot be evaluated at all — on a strict receiver that is worse than a plain fail. This happens constantly: a new provider's setup wizard adds its own record instead of editing yours. Merging them means one record carrying both sets of mechanisms, not two records.

The ten-lookup limit, the quiet killer

This is the single most common cause of an SPF record that looks perfect and fails anyway.

The specification caps SPF evaluation at ten DNS lookups. Every include:, a, mx, ptr and exists: costs one — and the lookups inside each included record count too. One include: that itself contains three includes costs four of your ten. Exceed the limit and the result is permerror: not a fail, but an unevaluable record, which many receivers treat as unauthenticated.

What makes it so nasty is that it is invisible and it creeps. Your record passed when you wrote it. Months later one of your providers added an include: to their own record, your total crossed ten, and your mail started being flagged with nothing on your side having changed. ip4: and ip6: cost zero lookups, which is the main lever you have.

Count yours before assuming the record is fine. Query the TXT record for your domain, then query each included domain's record, and keep going until nothing is left to expand. A DNS lookup tool makes this quick: look up the TXT record, then follow each include: one at a time.

Why mail fails when the record looks right

If the record is syntactically valid and inside the lookup limit, work through these in order.

  • Something sends from an unlisted service. The usual suspects are a CRM, an invoicing or ticketing system, a marketing platform, a monitoring tool or an application server sending through its own local mail agent. Each needs an include: or its IP range.
  • The envelope sender is a different domain. A platform sending “on behalf of” you often uses its own return path, so SPF is checked against their domain and passes while your DMARC alignment still fails. The message can be authenticated and unaligned at the same time.
  • A subdomain with no record of its own. SPF does not inherit. Mail from mail.example.com is checked against that exact name, and if it has no TXT record the result is none, not your apex policy. Publish a record per sending subdomain, and an empty v=spf1 -all on subdomains that should never send.
  • The record changed and caches have not caught up. Your TXT record carries a TTL like any other, so a fix is not live everywhere the moment you save it — how TTL and propagation work covers the timing.
  • A stale include:. A provider you stopped using whose domain no longer resolves can produce a permerror, and it is in nobody's interest to tell you.

Forwarding breaks SPF, by design

This one is not your fault and cannot be fixed in your record, so it is worth understanding before you spend a day on it.

When a recipient forwards your message — a university alias, a .forward rule, a mailing list — the forwarding server connects to the final destination using its own IP address while keeping your domain as the envelope sender. The receiver checks your SPF record against an IP you have never heard of, and it fails. Correctly: that IP genuinely is not authorised by you.

Two mitigations exist, and neither is an SPF change. DKIM signs the message cryptographically and survives forwarding, so a forwarded message that fails SPF can still pass DKIM and therefore DMARC — which is the main reason to run both. SRS (Sender Rewriting Scheme) is the forwarder's job: it rewrites the envelope sender into its own domain so SPF is checked against the forwarder instead. You cannot make a remote forwarder do that.

The practical conclusion: never diagnose SPF from a forwarded copy of a message, and do not move to -all on the assumption that every failure you see is an attacker.

SPF passing is not the same as DMARC passing

A result of pass in the headers while DMARC still fails confuses almost everyone, and the reason is alignment.

SPF authenticates the envelope sender. DMARC additionally requires that the authenticated domain match the visible From: domain. A platform that sends with its own return path can give you a clean SPF pass on its domain, which does nothing for your From: domain — the SPF check passed, the alignment check did not, and DMARC fails on that basis.

So SPF alone was never a spoofing defence: an attacker can publish perfectly valid SPF for their own domain and still put your name in the From: field. DMARC is what ties authentication to the address the recipient actually sees, and it is also what sends you the reports that tell you who is sending as you. The guide to SPF, DKIM and DMARC covers how the three fit together and how to roll out a policy.

How to fix a failing record

In this order, because each step removes causes the later ones would otherwise hide.

  • Confirm there is exactly one record. Query your TXT records and count how many begin v=spf1. More than one is a permerror — merge the mechanisms into a single record first, before investigating anything else.
  • Count the lookups, including nested ones. If you are at or near ten, replace the heaviest include: with the ip4: ranges it resolves to, and remove includes for providers you no longer use. Dropping a single abandoned include often brings the whole thing back under the cap.
  • Inventory who actually sends for you. DMARC aggregate reports are the only reliable source here: they list every IP sending as your domain, including the systems nobody remembers. Guessing produces an incomplete record.
  • Drop ptr entirely. It is deprecated, slow, unreliable, and some receivers ignore records that use it.
  • Keep ~all until the reports are clean, then move to -all. A hard fail on an incomplete record bounces your own mail.
  • Lower the TTL before editing, then verify from outside. Check the live TXT record with a DNS lookup tool rather than trusting your DNS panel, and re-check after the old TTL has expired.

Common mistakes

  • Two SPF records because a provider's wizard added its own. Permerror, and worse than a fail.
  • Exceeding ten lookups and never finding out, because the failure is a permerror in someone else's logs.
  • Jumping to -all before you know every legitimate sender. The system you forgot is usually the one that invoices your customers.
  • Expecting subdomains to inherit. They do not. Publish a record per sending subdomain.
  • Using ptr, or +all, which authorises everyone.
  • Diagnosing from a forwarded message. Forwarding fails SPF legitimately and tells you nothing about your record.
  • Assuming an SPF pass means DMARC passes. Without alignment to the visible From: domain, it does not.
  • Editing the record and testing immediately. The old TXT record is still cached for the length of its TTL.

The short version

SPF compares the connecting IP against one TXT record and checks the invisible envelope sender, not the From: address your recipient reads. Publish exactly one record, keep the total DNS lookups — including the ones nested inside every include: — at ten or fewer, list every service that legitimately sends for you, give each sending subdomain its own record, and stay on ~all until your DMARC reports prove the list is complete. Forwarded mail will fail SPF no matter what you do, which is why DKIM and DMARC exist alongside it. Read the live TXT record for any domain, expand each include: and see the remaining TTL with the free DNS lookup tool.

Related tools and guides:

Frequently Asked Questions

Why does my SPF record keep failing?⌄

The three usual causes are more than one SPF record on the domain, which is a permerror; exceeding the ten DNS lookup limit once the lookups nested inside your include: terms are counted; and mail leaving from a service the record does not list. Forwarded mail also fails legitimately and is not a fault in your record.

What is the SPF ten-lookup limit?⌄

SPF evaluation is capped at ten DNS lookups. Every include:, a, mx, ptr and exists: term costs one, and the lookups inside each included record count toward your total as well. Going over returns permerror, which many receivers treat as unauthenticated. ip4: and ip6: terms cost no lookups, so replacing a heavy include: with its ranges is the usual fix.

Should I use ~all or -all?⌄

Use ~all, a soft fail, while you are still identifying every system that legitimately sends for your domain, then tighten to -all once your DMARC aggregate reports show nothing unexpected. Moving to -all on an incomplete record causes receivers to reject your own mail.

Can I have two SPF records?⌄

No. A domain may publish only one record starting with v=spf1, and two of them is a permerror that cannot be evaluated at all. It usually happens when a new provider’s setup wizard adds a record instead of editing the existing one. Merge the mechanisms into a single record.

Why does forwarded mail fail SPF?⌄

Because the forwarding server connects using its own IP address while keeping your domain as the envelope sender, so the receiver checks your record against an address you never authorised. Nothing in your record can fix it. DKIM survives forwarding, which is why a forwarded message can still pass DMARC through DKIM alone.

About the author
Founder & CEO, BuildToolForge
Follow on X: @Buildtoolforge

15+ years of hands-on experience in web development and security. Focused on practical web security: keeping websites secure, reliable and easy to troubleshoot. BuildToolForge exists to make these checks free, private and understandable. Tools run in your browser wherever possible, and nothing you enter into a tool is stored.

How we write our guides: Every guide is written from hands-on experience, checked against the official standards, and tested with our own tools on real domains. We update guides when standards or tools change. Found a mistake? Email contact@buildtoolforge.com.

Last updated: November 2, 2026