redirect is a lesser known feature of SPF that may cause some confusion about its intended use.
In this article we'll dive into SPF
redirect, when (not) to use it and how to avoid common pitfalls with it.
redirect is sometimes confused with
include, due to its similar name and functionality.
But there are some essential differences which can cause hard to trace down deliverability issues if used incorrectly.
A redirect is a pointer to another domain name that hosts an SPF policy, it allows for multiple domains to share the same SPF policy. It is useful when working with a large amounts of domains that share the same email infrastructure.
redirectis not a mechanism
The various matching rules in an SPF record are created with mechanisms.
Common mechanisms are
redirect is not an SPF mechanism, it is known as a modifier.
Modifiers differ in syntax from mechanisms. A mechanism may contain a value, which is separated using a colon. A modifier must contain a value and it is separated with an equal sign (=).
v=spf1 include:_spf.mailhardener.com -all
v is a modifier, its value
spf1 is separated with an equal sign (=). The
include is a mechanism, its value
_spf.mailhardener.com is separated with a colon (:).
Be aware to use the correct separator for the
The mechanisms in an SPF record are evaluated from left to right. But since
redirect is not a mechanism, it is evaluated after the mechanisms.
It is therefore recommended to place the
redirect at the very end of the SPF record, to clarify that it is only used if the preceding mechanisms didn't match.
The position of the redirect modifier in the SPF record has no functional effect.
The redirected domain is only used if no other mechanism matches. All mechanisms are first evaluated, and only if none of those match the email sender is the redirect used.
It is important to realise that the
all mechanism always matches.
So if there as an
all mechanism anywhere in the record, the
redirect is completely ignored.
An SPF record with a
redirect should not contain the
Consider the following example:
mailhardener.com "v=spf1 redirect=_spf.mailprovider.com -all" _spf.mailprovider.com "v=spf1 ip4:18.104.22.168/16 ~all
When the example above is evaluated, it will always result in
-all, the redirect is completely ignored.
This means that in this example, no senders will pass SPF validation, even from
redirectchanges the domain name.
ptr the value is optional.
If no value is set it defaults to the current domain.
But when a
redirect is used, the
ptr mechanism will point to the redirected domain.
mailhardener.com "v=spf1 a -all"
a mechanism has no value, so it points to the DNS
A record of
mailhardener.com, because that's where the SPF record is hosted.
But now consider the following situation:
mailhardener.com "v=spf1 redirect=_spf.mailhardener.com" _spf.mailhardener.com "v=spf1 a -all"
In this example the
a mechanism points to the DNS
A record of
_spf.mailhardener.com, even though it was redirected to by the
mailhardener.com root domain.
This is a common cause of SPF validation issues, and hard to debug.
If you use SPF
redirect, be aware that if the redirected SPF record has an
ptr mechanism without an explicitly set domain name, it will point to the redirected domain.
Unlike with the
include mechanism, the
redirect modifier will cause the
all mechanism of the redirected domain to be used.
That is, of course, because when working with the
redirect modifier, the root domain is not supposed to have the
all modifier set.
A common use-case with an
include is this:
mailhardener.com "v=spf1 include:_spf.mailprovider.com -all" _spf.mailprovider.com "v=spf1 ip4:22.214.171.124/16 ~all
For the example above, there are 2
all mechanisms. Because the
include does not affect the
all mechanism the
-all rule of the root domain is used and not the
~all rule of the included record.
redirect modifier does influence the
all mechanism, consider the following scenario:
mailhardener.com "v=spf1 redirect=_spf.mailprovider.com" _spf.mailprovider.com "v=spf1 ip4:126.96.36.199/16 ~all
When the example above is evaluated, the redirect is followed resulting in the
~all modifier being used for the root domain.
One interesting observation is the following:
mailhardener.com "v=spf1 include:_spf.mailprovider.com" _spf.mailprovider.com "v=spf1 ip4:188.8.131.52/16 ~all
This will actually result in a
?all (neutral) rule being used.
That is because without an
all mechanism explicitly set, the
?all policy is assumed.
The included SPF policy does not influence the
all mechanism of the SPF record that included it.
redirectretains error state
Normally, if a domain has no SPF record, the SPF evaluation will return a
none error, meaning that the receiver will take a neutral stance in examining the email.
redirect to a domain that does not have an SPF policy, or the SPF policy contains a syntax error, the SPF validation will fail with a
This usually results in the email failing SPF validation.
include mechanism if the included policy does not exist or contains a syntax error, the evaluation continues.
softerror may be reported with DMARC, but a sender can still pass SPF validation if it matches any other mechanism.
redirectcounts as a DNS query
The SPF RFC7208 limits to the number of additional DNS queries required to fully evaluate an SPF record to 10. The initial fetch of the SPF record does not count towards that total.
redict also increases this count. So be careful when using a
redirect, as you may exceed the limit of 10 DNS queries.
This may cause receivers to ignore your SPF policy.
You can use our SPF validator tool to test the number of required DNS queries to evaluate your SPF record.
redirect modifier can be used to consolidate a common SPF policy amongst a group of domains.
It is useful when working with a large amounts of domains that share the same email infrastructure.
However, there are many caveats that you should be aware of before attempting to implement
Unless you have a good reason to use the
redirect modifier, you are probably better of in using the
In hindsight the names for
redirect were poorly chosen. RFC7708 also admits that in section 5.2.
redirect modifier should have been called
include, and it would have been better if
include was called something like