Email6 min read

What ~all, -all and ?all Actually Do in an SPF Record

The last few characters of your SPF record decide what happens to every server you did not list — which is to say, every server an attacker would use. Two of the four options mean "no policy at all", and one of them is the default when you leave the qualifier off.

By ShipReady

all is a mechanism that matches every sender, so it decides the result for any server your record did not otherwise authorise. Its qualifier is the policy: -all means fail (this server is not authorised), ~all means softfail (probably not authorised, accept but mark), ?all means neutral, and +all means pass. Neutral must be treated by receivers exactly as if you had published no SPF record at all, and +all explicitly vouches for every server on the internet. If your record ends in ?all or +all, or has no all at all, SPF is doing nothing for you.

The four qualifiers

Every SPF mechanism can carry a qualifier. In practice it is only ever interesting on all, because that is the one that catches everything you did not list.

WrittenResultWhat it tells a receiver
-allFailAn explicit statement that this server is not authorised to send for the domain. Receivers may reject the message outright.
~allSoftFailA weak statement of non-authorisation. The message should be accepted but marked — in practice, weighted towards spam.
?allNeutralNo assertion either way. Receivers must treat this exactly as if no SPF record existed.
+allPassEvery server on the internet is authorised to send mail as you. This is almost never intended.
From RFC 7208 §4.6.2 and §2.6.

The two rows worth dwelling on are the bottom two, because they are the ones that look like a policy and are not.

Neutral is indistinguishable from having no record

RFC 7208 §2.6.2 is unusually direct about this: a neutral result "MUST be treated exactly like the None result". A record ending ?all authorises your own senders and says nothing whatsoever about anyone else. Every SPF checker will report the record as valid, because it is — it just does not do the job you published it for.

A bare all means +all

This is the trap. The default qualifier is +, so a record ending in a bare all with no prefix resolves to a pass. v=spf1 include:_spf.google.com all does not mean "and that is the end of the list" — it means "and everyone else is fine too". Your record now actively vouches for the server sending forged mail as you, which is worse than publishing nothing at all. ShipReady rates an SPF record that authorises any server as high severity for exactly that reason.

No all at all

If evaluation runs off the end of the record without matching anything, the result is neutral — the same as ?all. A record with no terminal mechanism therefore authorises your senders and leaves everyone else unaddressed. ShipReady reports this as an SPF record that says nothing about servers it does not list, separately from the permissive-all case, because they read differently even though they land in the same place.

The exception is a record ending in a redirect= modifier, which hands evaluation to another domain’s record. That is a legitimate structure and the redirected record supplies the terminal mechanism.

So: ~all or -all?

This is the actual question people arrive with, and the honest answer is that it matters less than it used to — provided you have DMARC.

On its own, SPF is a poor basis for rejecting mail, because it breaks on forwarding. When a recipient auto-forwards your message, the forwarding server connects from an IP your record does not list, and SPF fails through no fault of yours. A -all invites receivers to reject that legitimate message.

DMARC changes the calculation. It evaluates whether an aligned SPF or an aligned DKIM passed, and DKIM survives forwarding. So with DKIM signing in place and a DMARC policy at p=reject, forwarded mail still authenticates via DKIM, and the SPF qualifier stops being the thing standing between a forged message and an inbox.

Your setupReasonable endingWhy
SPF only, no DKIM or DMARC~allYou have no second mechanism, so a hard fail will lose legitimate forwarded mail.
SPF + DKIM + DMARC at p=none~allYou are still in the observation phase. Do not tighten SPF before you understand your own sending.
SPF + DKIM + DMARC at p=reject~all or -allEither is defensible. DMARC is doing the enforcing; -all adds a signal for receivers that evaluate SPF standalone.
A domain that sends no mail at all-allThere is no legitimate mail to break. Publish v=spf1 -all and a strict DMARC record.

If you want one rule: use ~all while you are setting things up, and treat getting to DMARC `p=reject` as the goal rather than tightening SPF. A hard SPF fail on a domain with no DMARC is a weaker position than a soft fail on a domain with enforcement.

Reading a record end to end

dns
v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.10 ~all
  1. v=spf1 — the version. Required, and it is how receivers tell an SPF record from every other TXT record on the domain.
  2. include:_spf.google.com — if Google’s record would pass this sender, pass. Costs at least one DNS lookup.
  3. include:sendgrid.net — likewise for SendGrid.
  4. ip4:203.0.113.10 — authorise this address directly. Costs no lookup.
  5. ~all — everything else softfails.

Mechanisms are evaluated left to right and the first match wins, which is why all must be last: anything after it is unreachable.

The limit that breaks records quietly

SPF evaluation may perform at most ten DNS lookups (RFC 7208 §4.6.4). include:, a, mx, ptr, exists and redirect= each cost one, and an include: that itself contains includes costs the sum. Exceed ten and evaluation returns permerror — which most receivers treat as no usable SPF result, making your carefully chosen all qualifier irrelevant.

It creeps up on you: four providers, each with a nested include, and you are over. When you hit it, remove providers you no longer use before doing anything cleverer — most domains have an include: for a service they stopped paying for two years ago. ShipReady reports an SPF record over the lookup limit, and a syntax error when the record does not parse at all.

Check yours

shell
dig +short TXT yourdomain.com | grep spf1
  • Exactly one line should come back. Two SPF records disable SPF entirely.
  • Read the last mechanism. If it is ?all, a bare all, or missing, that is the finding in this article.
  • Count the lookups if the record has more than three or four include: entries.

How ShipReady checks it

ShipReady resolves the SPF record for the domain you scan and evaluates its contents rather than its existence: whether it ends in a qualifier that resolves to a pass, whether it has no terminal mechanism, whether it parses, whether it stays under the lookup limit, and whether more than one record is published.

It reads public DNS only, the same answers any receiving mail server gets. Scan your domain free for the whole Email pillar, or start with what SPF, DKIM and DMARC each prove if the three records still blur together.

Frequently asked questions

Will changing `~all` to `-all` break my email?
It can, if any legitimate source is missing from your record or your mail gets forwarded. Move to `-all` only after DMARC aggregate reports have shown you every source that sends as you, and after DKIM is signing.
Is `+all` ever correct?
No. It is an explicit statement that any server may send as your domain, which makes SPF vouch for forgeries. It usually appears by accident, from a bare `all` or from copied advice about "fixing" delivery failures.
Does the `all` qualifier matter if I have DMARC at p=reject?
Much less. DMARC does the enforcing, and it needs an aligned pass from SPF or DKIM. The qualifier still matters for receivers that evaluate SPF on its own, so `~all` remains the sensible floor.
What about `exp=`?
It names a domain holding an explanation string for a fail result, which some receivers include in the rejection message. It is optional, costs a lookup only when a fail actually occurs, and does not affect the policy.

Sources

Related reading

Is your site ready to ship?

ShipReady scans up to ten pages for security, AI exposure, email deliverability, SEO and launch readiness — with a paste-ready fix for each finding. Free, no signup.