"Received-SPF: softfail" — Causes & Fix

A receiver marked your message spam or rejected it because SPF returned softfail (~all) or neutral (?all). Here is what those qualifiers mean and how to make SPF pass.


"Received-SPF: softfail" means the sending IP was not listed in your SPF record, and your record ends in ~all (softfail) — a "probably not authorized, but don't hard-reject" verdict. neutral is the same idea with ?all ("no assertion"). Neither is a pass. Many receivers accept softfail but drop it in spam, and stricter ones — or a failing DMARC — will reject it outright. The fix is to add the sending source to your SPF record so it evaluates to pass before ever reaching the ~all catch-all.

What It Looks Like

The verdict appears in the Received-SPF and Authentication-Results headers, and sometimes in a bounce from a receiver that treats softfail as a rejection:

text
# The SPF result on a delivered (often spam-foldered) message Received-SPF: softfail (google.com: domain of transitioning user@example.com does not designate 203.0.113.9 as permitted sender) client-ip=203.0.113.9; Authentication-Results: mx.google.com; spf=softfail (sender IP is 203.0.113.9) smtp.mailfrom=example.com; dmarc=fail (p=REJECT) header.from=example.com # Neutral — the record made no assertion (?all) Received-SPF: neutral (example.net: 203.0.113.9 is neither permitted nor denied) # A stricter receiver rejecting softfail 550 5.7.23 SPF softfail - sender not authorized for example.com

The tell is the phrase "does not designate … as permitted sender" together with softfail or neutral rather than pass. The IP in client-ip= is the sender you need to authorize.

Look up your SPF record and see what it permits

What the SPF Qualifiers Mean

Every mechanism in an SPF record has a qualifier, and the all at the end sets the default verdict for any IP that did not match earlier. The four qualifiers are:

  • +allpass everything. Never use it; it authorizes the whole internet.
  • -allfail (hard). Anything not listed is unauthorized; receivers may reject.
  • ~allsoftfail. Not authorized, but accept-and-mark (usually spam).
  • ?allneutral. No assertion; treated as barely better than nothing.

softfail and neutral are both "not a pass." They exist as a lenient middle ground while you are still discovering your senders — but leaving legitimate mail to rely on them means inconsistent inboxing and, under DMARC enforcement, outright rejection.

softfail is not the goal — pass isGetting to ~all instead of a hard fail does not fix deliverability; it just makes the failure quieter. The objective is spf=pass for every legitimate sender. The ~all/-all at the end only decides what happens to mail you did not authorize.

Why It Happens

1. The sending service is not in your SPF record

The core cause. You send through a provider (a CRM, ESP, helpdesk, or new mail host) whose IPs are not covered by any mechanism in your record, so evaluation falls through to ~all and returns softfail.

2. You send from a new IP that the record predates

You migrated mail servers or added a second sending IP, but the SPF record still lists only the old one. Mail from the new IP soft-fails until you add it.

3. The record still ends in ?all from initial setup

Some setup wizards publish ?all (neutral) as a placeholder. It provides no protection and produces neutral verdicts; it should be tightened to ~all or -all once your senders are known.

4. Forwarding changed the sending IP

When a message is auto-forwarded, the forwarder becomes the sender, so its IP is not in your SPF and the result is softfail at the final hop. This is an inherent limitation of forwarding — DKIM is what survives it.

Why softfail still hurts under DMARCDMARC needs SPF (or DKIM) to pass and align. A softfail is not a pass, so unless DKIM is passing and aligned, DMARC fails — and a p=reject policy turns your quiet softfail into a hard bounce. Fixing SPF (or adding aligned DKIM) resolves both.

How to Diagnose It

Pull the client-ip= from the header, then look at your SPF record and confirm whether any mechanism actually covers that IP before the all:

bash
# Your SPF record — what does it authorize, and how does it end? dig TXT example.com +short | grep spf1 # e.g. "v=spf1 include:_spf.google.com ~all" <- ends in softfail # Does the failing IP fall under any include/ip4/a/mx mechanism? # Expand the includes to see the covered ranges: dig TXT _spf.google.com +short
See which senders your SPF actually permitsThe SPF Lookup expands every mechanism so you can tell whether the failing IP is covered before ~all.
Look up SPF now

How to Fix It

Fix A — Authorize the sending source

Add the service to your SPF record using the include: its provider publishes, or the ip4:/ip6: ranges of your own mail server. Keep a single SPF record and stay under the 10-lookup limit:

text
; Before — only Google is authorized, everything else soft-fails example.com. 3600 IN TXT "v=spf1 include:_spf.google.com ~all" ; After — add the new sender (e.g. SendGrid) so it passes example.com. 3600 IN TXT "v=spf1 include:_spf.google.com include:sendgrid.net ~all"

Use the SPF generator if you are building the record from scratch or merging several senders into one line.

Fix B — Add your own server's IP directly

If you send from a self-hosted server or a static IP, list it explicitly. Literal IP mechanisms cost no DNS lookups and are the most reliable way to authorize a fixed sender:

text
example.com. 3600 IN TXT "v=spf1 ip4:203.0.113.9 include:_spf.google.com ~all"

Fix C — Tighten ?all to ~all (or -all)

A record ending in ?all gives no protection. Once you are confident every legitimate sender is listed, tighten the catch-all so unauthorized mail is actually discouraged. Move to -all only after monitoring confirms nothing legitimate is being missed:

text
; Neutral — no protection example.com. 3600 IN TXT "v=spf1 include:_spf.google.com ?all" ; Softfail — reasonable default once senders are known example.com. 3600 IN TXT "v=spf1 include:_spf.google.com ~all" ; Hard fail — strongest, once you are certain the list is complete example.com. 3600 IN TXT "v=spf1 include:_spf.google.com -all"

Fix D — Add aligned DKIM so forwarding survives

SPF cannot survive forwarding, so for mail that gets forwarded (or sent via a provider with its own Return-Path), pair SPF with aligned DKIM. DKIM keeps DMARC passing even when SPF soft-fails at the final hop.

Do not jump straight to -allSwitching to -all before every legitimate sender is authorized will hard-fail real mail. Stay on ~all, watch your DMARC reports until all sources pass, and only then consider -all. Never "fix" a softfail by loosening to ?all or +all.

Verify the Fix

Confirm the sender now passes SPFRe-check the record, then send a test and confirm spf=pass instead of softfail.
Verify SPF now

DNS changes only take effect once the old record's TTL expires. After updating, confirm the record is live, send a test message from the previously soft-failing source, and check that its headers now show spf=pass:

bash
# Confirm the updated record is live dig TXT example.com +short | grep spf1 # Send a test to a mailbox you control, then in the raw headers look for: # spf=pass (google.com: domain of user@example.com designates 203.0.113.9 # as permitted sender) smtp.mailfrom=example.com

You can also send to a Gmail address and use Show original, or paste the full source into the Email Header Analyzer to confirm the SPF verdict is now a pass.

Frequently Asked Questions

Is softfail a pass or a fail?

A fail — just a soft one. ~all tells receivers the IP is not authorized but asks them not to hard-reject. It is not spf=pass, so it does not satisfy DMARC and often lands in spam.

Should I change ~all to -all to stop the softfail?

No — that makes it stricter, not passing. -all hard-fails everything unlisted, which would reject the very mail you are trying to deliver. The fix is to add the sender so it passes; the catch-all only governs unauthorized mail.

What is the difference between softfail and neutral?

softfail (~all) says "probably not authorized." neutral (?all) says "no opinion." Neutral offers even less protection and is usually a leftover placeholder that should be tightened to at least ~all.

Why does my mail softfail only when forwarded?

Forwarding replaces the sending IP with the forwarder's, which is not in your SPF record, so the final hop soft-fails. There is no SPF-only fix for this; aligned DKIM survives forwarding and keeps DMARC passing.

Can softfail cause a bounce, or only spam-foldering?

Both. Lenient receivers accept and mark it; stricter ones reject softfail directly. And if DMARC is enforcing and DKIM is not aligned, softfail leaves DMARC nothing to pass on, producing a hard bounce.

Related