SPF softfail vs hardfail
See which qualifier your record ends in, and whether moving to -all is safe yet.
What you are seeing
- spf=softfail (domain of transitioning example.com does not designate 203.0.113.5 as permitted sender)
- spf=fail (domain of example.com does not designate 203.0.113.5 as permitted sender)
- An SPF record with a hard fail
What it means
The last mechanism in an SPF record is a catch-all with a qualifier. `~all` is softfail: the server is not authorised, but the receiver is asked to accept the message and mark it. `-all` is hardfail: the server is not authorised and the receiver may reject.
Both are *failures* for DMARC purposes. DMARC does not distinguish softfail from hardfail — neither one can produce an aligned SPF pass. If you are relying on DMARC, the qualifier changes how non-DMARC receivers behave, not whether DMARC passes.
A hard fail still often lands in the inbox. `-all` is advisory; large receivers weigh it alongside DKIM, reputation and DMARC rather than rejecting on it alone. This is why "I set -all and spoofing continues" is a DMARC problem, not an SPF one.
There is also `?all` (neutral, no assertion) and `+all` (authorise the entire internet). `+all` is always a misconfiguration.
Why it happens
- Forwarding
- A forwarder relays your message from its own IP without rewriting the envelope sender, so SPF checks an address your record does not list. This is the single most common legitimate SPF failure and it is why DKIM matters.
- A sending tool you forgot
- Invoicing, CRM, support desk, CI notifications and form plugins all send as your domain. Each one needs to be in SPF or to sign with aligned DKIM.
- The envelope sender is the provider, not you
- Many bulk tools use their own MAIL FROM domain. SPF then passes for *their* domain and is simply not aligned with yours, which looks like a failure in DMARC reports even though SPF itself passed.
- A record left on ~all during a migration that never ended
- `~all` was designed as a transition state. Records sit in it for years, which leaves receivers without a clear signal.
How to fix it
- 1Confirm what your record ends in. Run the check above. It reports the final qualifier, plus any permissive mechanism earlier in the record that makes the ending irrelevant.
- 2Publish DMARC with reporting before you tighten SPF. Start at `p=none` with a `rua` address. The aggregate reports tell you every IP sending as your domain and whether SPF and DKIM aligned. Tightening SPF without that data is guessing.
- 3Get aligned DKIM working first. DKIM survives forwarding; SPF does not. With aligned DKIM in place, a forwarded message still passes DMARC, so `-all` stops being risky.
- 4Switch to -all once reports are clean. When a few weeks of reports show no legitimate source failing both SPF and DKIM, change the qualifier. Keep reading reports for a week after.
Questions
- Is ~all or -all better?
- -all, once every legitimate sender is listed or signing with aligned DKIM. Until then ~all avoids breaking mail you have not accounted for. Neither one affects whether DMARC passes.
- Why does mail still get delivered with -all?
- SPF is advice, not an instruction. Receivers combine it with DKIM, DMARC and reputation. If you want spoofed mail actually stopped, the lever is a DMARC policy of quarantine or reject.
- What does "transitioning" mean in a softfail message?
- It is the wording receivers use for `~all`: your record says this server is not authorised but that you are still working out your sender list.
- Does -all break email forwarding?
- It can, for receivers that act on SPF alone and for forwarders that do not rewrite the envelope sender. Aligned DKIM is what makes forwarded mail survive, which is why DKIM comes before -all.
Fix this from ChatGPT or Claude
MailVakt is an MCP server, so your assistant can run this check itself, read the findings and walk you through the DNS edit. Ask it:
“Check the SPF record for example.com and tell me whether it is safe to change ~all to -all, and which senders would start failing.”
- Claude: Settings → Connectors → Add custom connector, then paste
https://mcp.mailvakt.com/mcp. - Cursor and other MCP clients: add the same address as an MCP server. Setup details.
Checks are free and need no account. Sign in only to collect DMARC reports for a domain.