SPF Fail, Softfail, Permerror and Temperror: What Each Means
SPF fail means the sending IP isn't authorized, softfail means probably not, permerror means your record is broken, and temperror means DNS hiccupped.
On this page
SPF gives every message one of seven results, and four of them are problems. Fail means the sending IP is not in your SPF record and your record ends in -all. Softfail means the same thing with ~all: the IP is "probably not" authorized. Permerror means your record is broken (two records, a syntax error, or more than 10 DNS lookups) and can't be evaluated at all. Temperror means the receiver hit a temporary DNS problem and couldn't finish the check.
The fix depends on which one you have. Fail and softfail usually mean a sending service is missing from your record, or the mail was forwarded. Permerror is always a record problem you fix in DNS. Temperror is usually transient, unless your DNS is unreliable.
Where to find your SPF result
Open the headers of a message that failed (or a copy sent to a mailbox you control) and look for the Authentication-Results header the receiver added. The SPF part looks something like this (an illustrative line, built from the format in RFC 8601):
Authentication-Results: mx.example.net;
spf=softfail smtp.mailfrom=bounces.example.com
Note the result (softfail) and the domain SPF checked (smtp.mailfrom=). SPF checks the envelope sender (the Return-Path or MAIL FROM), not the visible From address. With an email service provider, that domain is often theirs or a subdomain you delegated, so make sure you're editing the right record.
The header analyzer will pull these results out for you, and how to read an email header walks through the rest.
The seven SPF results
RFC 7208, the SPF specification, defines all of them:
| Result | What it means | Typical cause |
|---|---|---|
| pass | The IP is authorized for the domain | Working as intended |
| fail | Explicit statement the IP is not authorized | IP not in the record, record ends in -all |
| softfail | "Weak statement" the IP is probably not authorized | IP not in the record, record ends in ~all |
| neutral | Domain makes no assertion either way | Record ends in ?all, or no mechanism matched and there's no all |
| none | No SPF record found | No record published, or the domain doesn't exist |
| permerror | The record can't be interpreted; needs a DNS fix | Two records, syntax error, over 10 lookups, broken include |
| temperror | A transient error, usually DNS | DNS timeout or server failure |
One thing that trips people up: a record with no all at the end doesn't default to fail. If nothing matches, the RFC says the result is neutral, as if the record ended in ?all.
SPF fail (hard fail)
Fail is your own record saying "this server isn't one of mine." The qualifier in front of all decides what an unmatched IP gets: - gives fail, ~ gives softfail, ? gives neutral. So with this record:
v=spf1 include:_spf.example-esp.com ip4:203.0.113.7 -all
mail sent from 198.51.100.20 gets fail, because nothing in the record covers it.
RFC 7208 says receivers that reject on fail should use 550 5.7.1. Gmail rejects some hard fails with 550 5.7.26 and a message that names the -all policy; the 550 5.7.26 page has the exact text.
Common causes, most likely first
- A sending service that isn't in your record. A new CRM, helpdesk, billing system or HR platform starts sending as your domain and nobody added its include.
- Forwarding. When a message is forwarded, the forwarding server becomes the sender, and its IP isn't in your record. Google says plainly that forwarded messages often fail SPF. You can't fix this in your record; it's why DKIM matters.
- Someone spoofing your domain. In that case SPF is doing its job.
- An IP change. You moved mail servers or your provider changed ranges, and a hardcoded
ip4:is now stale.
SPF softfail
Softfail has the same causes as fail. The only difference is what you told receivers to do about it. RFC 7208 says receivers should not reject on softfail alone, though they may give the message closer scrutiny.
Don't treat softfail as harmless. For DMARC, anything other than pass is a failure, so a softfail counts exactly as much as a fail. Microsoft's documentation makes the point directly: DMARC treats both -all and ~all as SPF failures, and it recommends -all for Microsoft 365 domains that also use DKIM and DMARC.
SPF permerror
Permerror means the receiver couldn't evaluate your record. The RFC describes it as an error that "definitely requires DNS operator intervention." It's the most damaging result, because it doesn't fail one sender. It breaks SPF for every message, from every service, that depends on that record.
Causes, roughly in the order they turn up:
- More than 10 DNS lookups. Every
include,a,mx,ptrandexists, plusredirect, counts, including the ones nested inside your includes. Over 10 is a permerror. See the SPF 10 DNS lookup limit. - Two SPF records. A vendor's setup guide says "add this TXT record," someone adds a second
v=spf1record instead of editing the first, and both become useless. RFC 7208 and Microsoft both say multiple records produce permerror. - Syntax errors. Microsoft lists a few it sees: a trailing period after an include,
=instead of:, and a space after the colon. Any syntax error ends evaluation with permerror. - An include that points nowhere. If an included domain has no SPF record (a vendor retired its include, or there's a typo), the include returns permerror.
- Too many void lookups. The RFC says implementations should allow only two lookups that come back empty. More than that is a permerror.
A permerror can look intermittent. Evaluation stops when a mechanism matches, so services listed early in the record may still pass while the rest fail.
SPF temperror
Temperror means the receiver hit a transient error, usually a DNS timeout or server failure, while looking up your record or one of its includes. The RFC lets receivers either accept the message or defer it; if they defer, the recommended code is 451 4.4.3.
An occasional temperror is noise. A steady trickle means something on the DNS side is shaky, such as an unreliable DNS host or a slow vendor include. Microsoft recommends a TTL of at least 3600 seconds on SPF records to avoid lookup timeouts.
How to fix SPF failures, step by step
- Get the actual result and the domain checked. Pull
Authentication-Resultsfrom a failing message. Don't guess from the From address. - Look up the record for that exact domain. Run it through the email checker. If there are two records, a syntax problem or a dead include, that's your permerror.
- Count lookups. Use the SPF lookup counter. If you're over 10, remove services you no longer use, swap includes for
ip4:ranges where the vendor publishes stable ones, or move a sending stream to its own subdomain. - For fail or softfail, identify the sending IP. Find it in the
Receivedheaders or the bounce, figure out which service owns it, and add that service's include (once, to the one record). - Make sure DKIM is signing too. SPF can't survive forwarding. If DKIM passes with your domain, the message can still pass DMARC when SPF fails.
- Publish, then retest. DNS changes take effect as caches expire, so allow for your record's TTL before you conclude the fix didn't work.
How to confirm it's fixed
Send a test message from each service you changed to a mailbox you control and check that Authentication-Results shows spf=pass for the expected domain. If you publish DMARC, your aggregate reports are the better confirmation: within a few days you should see SPF passing for every legitimate source. If SPF fails everywhere at once in those reports, suspect a permerror. DMARC fail covers reading them.
How to keep it from coming back
- Make SPF part of onboarding any new sending tool. Someone checks the record and the lookup count before the tool goes live.
- Keep one owner and a list. Note which include belongs to which vendor and who uses it, so dead ones get removed.
- Rely on DKIM as well as SPF. Gmail's sender guidelines require SPF or DKIM for all senders and both for bulk senders. DKIM is the one that survives forwarding.
- Watch DMARC reports. They're the only place you'll see failures on mail you didn't know you were sending.
For the bigger picture, see SPF, DKIM and DMARC explained and what is an SPF record.
When to get help
If SPF keeps breaking as teams add tools, or your DMARC reports show failures from sources nobody can identify, it's worth having someone map your sending sources properly before you move DMARC to enforcement. Get in touch.
FAQ
Is SPF softfail bad?
For DMARC, yes: softfail is not a pass, so it counts the same as a fail. On its own, receivers aren't supposed to reject on softfail, but they can treat the message with more suspicion.
Should I use -all or ~all?
Both tell receivers the IP isn't authorized; -all says it more firmly. Microsoft recommends -all for domains that also use DKIM and DMARC. Either way, only switch once every legitimate sender is in the record.
Why does SPF fail on forwarded email?
The forwarding server sends the message from its own IP, which isn't in your SPF record. Google notes that forwarded messages often fail SPF, which is why DKIM signing matters.
What does SPF permerror mean?
Your SPF record can't be evaluated: you have two records, a syntax error, a broken include, or more than 10 DNS lookups. It breaks SPF for all of your mail until you fix the record.
Sources
- RFC 7208: Sender Policy Framework (SPF), sections 2.6, 4 and 8
- RFC 8601: Message Header Field for Indicating Message Authentication Status
- Microsoft Learn: Set up SPF to identify valid email sources for your Microsoft 365 domain
- Google: Best practices for forwarding email to Gmail
- Google: Email sender guidelines
Related guides
- DKIM Fail: Body Hash Did Not Verify, Signature Failed and Other CausesDKIM fails when the message changed after signing (body hash did not verify), the signed headers changed, or the receiver can't find a matching public key.
- DMARC Fail: Why DMARC Fails and How to Fix ItDMARC fails when neither SPF nor DKIM passes for a domain aligned with your From address. Usually a sender lacks custom DKIM. Here's how to find and fix it.
- DMARC Policy: p=none vs quarantine vs reject (and Getting to Enforcement)p=none only monitors, p=quarantine asks receivers to junk failing mail, p=reject asks them to refuse it. Start at none, fix your senders, then tighten.
- DMARC Record Syntax and Tags ExplainedA DMARC record is a TXT record at _dmarc.yourdomain with tags for policy, reporting and alignment. Here's what each tag does and what's changed under DMARCbis.
- DMARC Reports: How to Read Aggregate (rua) and Failure (ruf) ReportsDMARC aggregate reports are daily XML summaries of every IP sending as your domain and whether it passed. Here's how to read them and what to do with them.
- SPF 10 DNS Lookup Limit, Void Lookups and SPF FlatteningSPF allows 10 DNS lookups per check. Go over and receivers return permerror, so SPF fails. Here's what counts, how void lookups work, and how to fix it.
Still stuck?
Some deliverability problems take an experienced eye to untangle. Tell me what you're seeing and I'll tell you what I'd check first. The first 30-minute call is free.