DEV Community

Cover image for The SPF redirect trap: why -all can make redirect= useless
Petr Michal
Petr Michal

Posted on

The SPF redirect trap: why -all can make redirect= useless

The SPF redirect trap: why -all can make redirect= useless

SPF records often look simple until you start combining mechanisms and modifiers.

One particularly easy mistake is to write a record like this:

v=spf1 include:_spf.google.com -all redirect=_spf.example.com
Enter fullscreen mode Exit fullscreen mode

At first glance, it seems reasonable:

  • authorize Google,
  • reject everything else,
  • and use another SPF policy through redirect=.

But the redirect= part will never be used.

The reason is an important detail of how SPF evaluation works.

redirect= is not a fallback after -all

An SPF record is evaluated mechanism by mechanism.

For example:

v=spf1 ip4:192.0.2.10 include:_spf.google.com -all
Enter fullscreen mode Exit fullscreen mode

The receiver checks the mechanisms until one matches.

The all mechanism is special because it always matches.

That means:

-all
Enter fullscreen mode Exit fullscreen mode

effectively says:

If nothing before this matched, return SPF Fail.

Now consider this record again:

v=spf1 include:_spf.google.com -all redirect=_spf.example.com
Enter fullscreen mode Exit fullscreen mode

Once SPF reaches -all, it already has a result.

There is no reason to evaluate redirect=.

The redirect modifier is only used when none of the mechanisms in the record produce a match.

Because all always matches, a record containing all prevents redirect= from being used.

What redirect= is actually for

The redirect modifier is useful when several domains should share one central SPF policy.

Imagine these domains:

example.com
example.net
example.org
Enter fullscreen mode Exit fullscreen mode

Instead of maintaining the same SPF configuration independently on every domain, they can redirect to a central policy.

For example:

example.com TXT "v=spf1 redirect=_spf.example.com"
example.net TXT "v=spf1 redirect=_spf.example.com"
example.org TXT "v=spf1 redirect=_spf.example.com"
Enter fullscreen mode Exit fullscreen mode

And the central record might contain:

_spf.example.com TXT "v=spf1 ip4:192.0.2.10 include:_spf.google.com -all"
Enter fullscreen mode Exit fullscreen mode

Now the sending policy can be maintained in one place.

This is very different from include:.

redirect= vs include:

These two are easy to confuse.

include:

Use include: when you want to authorize senders defined by another SPF record as part of your own policy.

Example:

v=spf1 include:_spf.google.com ip4:192.0.2.10 -all
Enter fullscreen mode Exit fullscreen mode

This says:

Google is allowed, this IP is allowed, and everything else should fail.

Your domain still owns the final policy.

redirect=

Use redirect= when another domain should provide the entire remaining SPF policy.

Example:

v=spf1 redirect=_spf.example.com
Enter fullscreen mode Exit fullscreen mode

A useful mental shortcut is:

include:  → add another policy
redirect= → use another policy
Enter fullscreen mode Exit fullscreen mode

That distinction matters when debugging SPF records.

A common broken configuration

Consider this:

v=spf1 ip4:192.0.2.10 -all redirect=_spf.provider.com
Enter fullscreen mode Exit fullscreen mode

Someone may expect the following behavior:

  1. allow 192.0.2.10,
  2. if it does not match, check _spf.provider.com,
  3. otherwise fail.

But SPF does not work that way.

The real evaluation is:

  1. check ip4:192.0.2.10,
  2. if it does not match, evaluate -all,
  3. all matches every sender,
  4. return SPF Fail,
  5. redirect= is never used.

If you really want the provider to define the policy, the record should instead look like:

v=spf1 redirect=_spf.provider.com
Enter fullscreen mode Exit fullscreen mode

If you want both your own IP address and the provider's authorized senders, include: is usually the appropriate mechanism:

v=spf1 ip4:192.0.2.10 include:_spf.provider.com -all
Enter fullscreen mode Exit fullscreen mode

The position of redirect= can be misleading

Another subtle point is that redirect= is a modifier, not a mechanism.

So it should not be read as if SPF simply processes it from left to right like ip4, include, mx, or all.

This record:

v=spf1 redirect=_spf.example.com -all
Enter fullscreen mode Exit fullscreen mode

does not mean:

Try redirect first, then -all.

The presence of the all mechanism still means SPF can produce a result without using the redirect.

A good mental model is:

Evaluate the SPF mechanisms first.
Only if none of them match can redirect= provide another SPF record to evaluate.

Why this matters in production

A broken SPF redirect can be surprisingly difficult to notice.

The DNS record is syntactically valid.

A DNS lookup succeeds.

The domain has an SPF record.

Yet mail from an expected sender may still fail SPF because the redirected policy was never evaluated.

This becomes especially confusing when organizations centralize SPF records across many domains.

A small mistake in the parent policy can affect multiple domains at once.

When debugging this kind of issue, check:

  1. whether the record contains an all mechanism,
  2. whether redirect= is actually reachable,
  3. whether you really need redirect= or should use include:,
  4. the SPF result returned by the redirected domain,
  5. the total number of DNS-querying SPF terms.

A simple rule to remember

If your SPF record contains:

-all
Enter fullscreen mode Exit fullscreen mode

and also:

redirect=...
Enter fullscreen mode Exit fullscreen mode

you should take a closer look.

In most cases, that combination indicates that the redirect is not doing what the author intended.

Use:

redirect=
Enter fullscreen mode Exit fullscreen mode

when another domain should define the SPF policy.

Use:

include:
Enter fullscreen mode Exit fullscreen mode

when another SPF policy should be incorporated into your own.

And use:

-all
Enter fullscreen mode Exit fullscreen mode

when you are ready to explicitly fail senders that did not match any previous mechanism.


If you are debugging a more complex configuration, I wrote a more detailed guide to the SPF redirect modifier, including redirect= vs include:, DNS lookup behavior, common errors, and practical examples.

You can also inspect an SPF record directly with the MXFend SPF checker.

Top comments (0)