SPF ~all vs -all: what each qualifier does in practice
Softfail or hard fail? How receivers treat ~all and -all today, why DMARC changed the calculus, and which ending to pick for each kind of domain.

On this page(8 sections)
- What the qualifiers mean on paper
- What receivers actually do with them
- Why DMARC changed the calculus
- The forwarding problem
- A practical decision table
- Common mistakes around all
- Putting mechanisms after all
- Omitting all entirely
- Using +all or ?all to "fix" failures
- Switching to -all before you know your senders
- How to check what you publish
- Bottom line
The last four characters of an SPF record start more arguments than the rest of it combined. ~all or -all?
The honest answer is that DMARC made the choice matter less than it used to, but not in the way most people assume.
What the qualifiers mean on paper
Every SPF mechanism can carry a qualifier that says what result to return when it matches. RFC 7208 defines four:
| Qualifier | Result | Intended meaning |
|---|---|---|
+ (default) |
pass | This host is authorized |
- |
fail | This host is explicitly not authorized |
~ |
softfail | Probably not authorized; accept but treat with suspicion |
? |
neutral | The domain makes no assertion |
The all mechanism matches everything, so it sits at the end and decides what happens to any IP that did not match an earlier term. -all says "anything else is unauthorized." ~all says "anything else is probably unauthorized, but I am not certain." ?all says nothing useful, and +all authorizes the entire internet to send as you, which you should never publish.
What receivers actually do with them
The specification leaves the response to a fail result up to the receiver. RFC 7208 permits rejecting a message during the SMTP transaction when SPF fails, but does not require it. In practice, receivers fall into a few camps:
- Large mailbox providers generally do not reject on SPF alone. SPF is one input to a reputation and filtering system that weighs DKIM, DMARC, sender history and content.
- Some smaller or self-hosted receivers do reject outright on
-allfails, usually through a policy daemon configured years ago. - Softfail is typically folded into the spam score rather than producing a rejection.
So -all is more likely to cause an outright bounce at a strict small receiver, while ~all is more likely to cause a quiet score bump. At the big providers the difference is usually small.
Why DMARC changed the calculus
Before DMARC, the all qualifier was the main lever a domain owner had to tell receivers how seriously to treat spoofing. DMARC gave domain owners a much better lever, with three advantages:
- It checks the visible From domain. SPF checks the envelope sender, which users never see. A spoofer can pass SPF for their own domain while forging your address in the From header. DMARC requires alignment between the two.
- It considers DKIM too. DMARC passes if either SPF or DKIM passes and aligns, so a forwarded message that breaks SPF can still pass on DKIM.
- It has an explicit policy.
p=quarantineorp=rejecttells receivers exactly what you want done with failures, instead of hoping they interpret-allthe way you intend.
For DMARC evaluation, softfail and fail are both simply "SPF did not pass." Once you have DMARC at enforcement, the qualifier on all no longer controls what happens to spoofed mail; your DMARC policy does.
The forwarding problem
The best argument for ~all is forwarding. When a recipient forwards your message from one mailbox to another, the forwarding server becomes the connecting IP. It is not in your SPF record, so SPF fails at the final destination.
If that final receiver hard-rejects on -all before considering DKIM or DMARC, the forwarded message bounces even though it was legitimate and DKIM-signed. With ~all, the receiver is less likely to reject at the SMTP stage and more likely to evaluate the full picture, where an intact DKIM signature can save the message.
This failure mode is real but shrinking. Most large receivers evaluate DMARC as a whole, and many forwarders now implement ARC or rewrite the envelope sender (a technique called SRS) so SPF evaluates against the forwarder's own domain.
A practical decision table
| Domain situation | Recommended ending | Why |
|---|---|---|
Domain sends mail, DMARC at p=none |
~all |
You are still discovering senders; avoid hard bounces from a missed source |
Domain sends mail, DMARC at p=reject |
~all or -all |
DMARC governs spoofing now; either is defensible |
| Domain never sends mail | -all |
No legitimate source exists to break |
| Subdomain used only by one provider | -all |
The sender list is short and fully known |
| Record you are actively changing | ~all |
Reduce risk while the change propagates |
Many experienced operators settle on ~all for primary sending domains with DMARC at enforcement and -all for parked domains and tightly scoped subdomains. That is a reasonable default, not a rule.
Common mistakes around all
Putting mechanisms after all
SPF evaluation stops at the first match, and all always matches. Anything after it is ignored:
v=spf1 ip4:192.0.2.10 ~all include:spf.sender.example
The include at the end never runs. Some validators flag this; many people miss it.
Omitting all entirely
A record without all and without a redirect= returns neutral for unmatched IPs. That is functionally close to ?all and gives receivers no signal at all.
Using +all or ?all to "fix" failures
When a legitimate source fails SPF, the temptation is to loosen the ending. +all makes SPF worthless and is widely treated as a spam signal in its own right. Find the missing source instead, using DMARC aggregate reports to identify the IPs that are failing.
Switching to -all before you know your senders
Tightening the ending while DMARC is still at p=none and you have not inventoried senders is how a billing system's invoices start bouncing at small receivers. Inventory first.
How to check what you publish
dig +short TXT example.com | grep -i spf1
Look at the final term. Then confirm there is exactly one SPF record on the name, that nothing follows all, and that every source in your DMARC reports either passes SPF or passes aligned DKIM.
Bottom line
-all and ~all differ mainly in how strict, older receivers react to an unauthorized IP. Once DMARC is enforcing, your DMARC policy decides what happens to spoofed mail and the SPF ending becomes a secondary signal. Use ~all while you are still learning which systems send as you, consider -all for parked domains and narrowly scoped subdomains, and never use +all or ?all to paper over a missing sender.
Start with Koltrix
Your domain, one inbox, and an API that sends.
A team inbox where AI sorts and drafts (nothing is sent without your click), plus the transactional API and SMTP relay your product sends with. 7 days free, no card.

