Guides · Email
SPF Record Failing? How To Read It In DNS
Your SPF record is a single TXT record in DNS. This guide shows how to find it, read every mechanism and qualifier, and diagnose the failures that break email delivery — softfail, the 10-lookup limit, and duplicate records.
By Cody · 7 min read · Published
The short version
An SPF record is not a special kind of record — it is one TXT record on your domain whose value starts with v=spf1. When receiving mail servers decide whether a message really came from you, they read that string and check whether the sending server is one you authorized.
So when “SPF is failing,” the answer is almost always sitting in plain text in your DNS. The three failures you will actually meet are a softfail that drops mail into spam, the 10-lookup limit that returns permerror, and a duplicate SPF record that invalidates both. Read the record correctly and each one is obvious.
Where SPF actually lives
SPF is published as a single TXT record on the domain that appears in the envelope sender — usually your root domain, example.com. The old dedicated SPF record type was deprecated years ago, so today it is always a TXT record. Pull the TXT records for your domain and find the one that begins with v=spf1:
v=spf1 include:_spf.google.com include:sendgrid.net ip4:198.51.100.10 ~all
Everything between v=spf1 and the trailing all is a list of mechanisms — the senders you authorize — evaluated left to right. The first one that matches the connecting server decides the result.
Reading the record, mechanism by mechanism
Each mechanism can carry a qualifier prefix. No prefix means + (pass). Here is everything you will see inside a real record:
| Token | Meaning |
|---|---|
v=spf1 | Version tag. Every SPF record must start with this. |
ip4: / ip6: | Authorize a specific address or CIDR range. Costs no DNS lookup. |
include: | Authorize another domain's SPF record (e.g. your ESP). Costs a lookup and can chain into more. |
a / mx | Authorize the domain's A or MX hosts. Each costs a lookup. |
ptr | Match on reverse DNS. Discouraged, slow, and lookup-heavy — avoid it. |
+ pass / - fail | Explicitly allow (+) or reject (-) a match. Bare mechanisms default to +. |
~ softfail / ? neutral | Accept-but-suspicious (~) or no opinion (?). Used almost exclusively on the final all. |
all | The catch-all at the end. Its qualifier decides what happens to unmatched mail. |
Why SPF fails — the three real cases
| Symptom | Cause | Fix |
|---|---|---|
| Mail lands in spam, header says softfail | A real sender is not listed, so ~all catches it. | Add the missing include / ip4 / mx before all. |
permerror / “too many DNS lookups” | The record needs more than 10 DNS lookups to evaluate. | Remove unused includes or flatten them to ip4 ranges. |
permerror / “multiple SPF records” | Two TXT records start with v=spf1. | Merge into one record; delete the duplicate. |
| Legitimate mail rejected outright | -all hardfail on an incomplete record. | Fix coverage first, or loosen to ~all while testing. |
temperror | A transient DNS failure while resolving a mechanism. | Usually self-resolves; re-check the record and its includes. |
The 10-lookup limit in practice
This is the failure that ambushes growing senders. SPF permits at most 10 DNS lookups per evaluation. Every include, a, mx, ptr, and exists mechanism spends from that budget — and an include pulls in another provider's record, which may contain its own includes. Three or four vendors is often enough to blow past 10.
When you exceed it, the receiver returns permerror, and many mailbox providers treat that as a straight SPF failure. Because ip4: and ip6: cost zero lookups, the standard fix is to replace some includes with the actual address ranges they resolve to (“flattening”), or to drop providers you no longer send through.
Reading SPF in the tools
Start with the TXT record lookup: it returns every TXT record on the domain, so you can spot the v=spf1 string, confirm there is only one, and read the mechanisms end to end. If you want to see the raw DNS answer and TTL alongside it, the DNS lookup tool shows the TXT record with its cache lifetime — useful right after a change, so you know how long the old value will linger.
Once SPF reads cleanly, the next records to check are DKIM and DMARC: SPF only authenticates the envelope sender, so see SPF, DKIM, and DMARC explained for how the three fit together, and MX records and email routing if inbound delivery is also involved.
An SPF record in a TXT lookup
- Example input
dig +short TXT example.com- Example result
"v=spf1 include:_spf.google.com include:sendgrid.net ip4:198.51.100.10 ~all" # read left to right: # include:_spf.google.com -> authorize Google Workspace senders (1+ lookups) # include:sendgrid.net -> authorize SendGrid senders (1+ lookups) # ip4:198.51.100.10 -> authorize this one IP (0 lookups) # ~all -> softfail everything else
Only one v=spf1 string should appear. If a second TXT record also starts with v=spf1, receivers return permerror and SPF fails for the whole domain.
Related tools
FAQ
Where is my SPF record stored?
In DNS, as a single TXT record on the exact domain that sends mail — usually the root domain (example.com), not a subdomain. It is an ordinary TXT record whose value starts with 'v=spf1'. There is no dedicated SPF record type any more; the old type 99 SPF record was deprecated, so everything lives in TXT. Look it up with a TXT query and read the string that begins with v=spf1.
Why does my SPF record show softfail instead of pass?
Softfail is the '~all' at the end of most records. It means 'mail from anything not listed above is probably not us, but accept it and mark it suspicious.' If a legitimate sender is not covered by one of your mechanisms, the receiver evaluates ~all, returns softfail, and the message often lands in spam rather than the inbox. The fix is to add the missing sender (an include, ip4, or a block) so it matches before the all mechanism is reached.
What is the SPF 10-lookup limit and why does it break delivery?
SPF allows at most 10 DNS lookups while evaluating a record. Every include, a, mx, ptr, and exists mechanism costs lookups, and includes chain into more includes. Exceed 10 and the receiver returns permerror, which many providers treat as an outright SPF failure. Large senders with several include statements hit this constantly. Flatten or consolidate includes, or remove providers you no longer use, to get back under 10.
Can I have two SPF records on one domain?
No. A domain must publish exactly one TXT record starting with v=spf1. If two are present — commonly one from your old provider and one from a new one — receivers return permerror and SPF fails entirely. Merge them into a single record by combining their include and ip4 mechanisms, then delete the duplicate.
What is the difference between -all and ~all?
Both are the final catch-all. '-all' is hardfail: mail not matched by an earlier mechanism should be rejected. '~all' is softfail: accept it but treat it as suspect. Start with ~all while you confirm every legitimate sender is listed, then tighten to -all once you are confident, because -all can cause valid mail to be rejected if your record is incomplete.
Does SPF check the From address I see in my mail client?
No, and this trips people up. SPF authenticates the envelope sender (the Return-Path / MAIL FROM), not the visible From header your recipient reads. That is exactly the gap DMARC closes by requiring alignment between the two. So an SPF pass alone does not prove the visible From is legitimate — you need DMARC on top for that.
How do I fix an SPF record that is failing?
Read the record top to bottom and confirm every service that sends mail for you is represented by an include, ip4, ip6, a, or mx mechanism. Verify there is only one v=spf1 TXT record, that you are under the 10-lookup limit, and that the record ends in ~all or -all. Publish the change, wait for the TTL to expire, then re-check the TXT record to confirm the new value is live before you tighten the policy.
Last reviewed: 2026-07-08.