Does "~all" in the middle of an SPF record signal the end of the record when it is parsed?

RFC 7208 § 5.1 is explicit about this: after all appears, everything after it MUST be ignored.

Mechanisms after "all" will never be tested. Mechanisms listed after "all" MUST be ignored. Any "redirect" modifier (Section 6.1) MUST be ignored when there is an "all" mechanism in the record, regardless of the relative ordering of the terms.

The RFC it obsoleted, RFC 4408, said much the same thing; the newer version of the RFC simply clarifies the intention.

Mechanisms after "all" will never be tested. Any "redirect" modifier (Section 6.1) has no effect when there is an "all" mechanism.

So, conforming implementations of SPF will completely ignore everything after the first ~all. This doesn't mean, however, that every implementation conforms to the spec. In particular, this was probably thought worthy of clarification precisely because one or more implementations did not conform.

It's not at all clear why an online validation tool would not catch this misconfiguration, but if you intend for anything after the first all to be used, you should correct the record, as proper implementations will ignore it.


"v=spf1 include:_spf.google.com ~all a mx ip4:X.X.0.0/23 include:spf.example.com ?all"

says in order:

"email passing SPF record of _spf.google.com is valid for our domain"

"softfail on all other senders for our domain"

"email coming from our A records are valid for our domain"

"email coming from our MX records are valid for our domain"

"email coming from IP range x.x.0.0/23 is valid for our domain"

"email passing SPF record of spf.example.com is valid for our domain"

"email from all other senders for our domain cannot be validated one way or the other"

Per the Record syntax:

Mechanisms are evaluated in order. If no mechanism or modifier matches, the default result is "Neutral".

So for yours once it hits the "softfail for all others" that's really about it...it should be ignoring the rest of the mechanisms you've specified.

Your SPF record should be as succinct as possible. I highly doubt you have an entire /23 network that should be sending email for your domain, nor should all your A records. Maybe so...but most likely not.

A nice clean SPF record should look something like:

"v=spf1 include:_spf.google.com include:spf.example.com mx -all"

Which would basically say that _spf.google.com, spf.example.com and your MX records are the only valid senders for your domain...everything else should be treated as invalid.