Back to blog
Threat Intel
Phishing Forensics

SPF `redirect` vs. `include`: It's About Delegation, Not Just DNS

Stop treating SPF `redirect` like a glorified `include` — one is a subroutine, the other is a hard handoff, and confusing them breaks your email delivery.

MailSleuth Research
Email Security Team
July 18, 20267 min read
Illustration of a highway fork representing the difference between SPF include (a brief detour) and SPF redirect (a new,

An analyst triaging a DMARC failure sees an SPF record with `redirect=_spf.anotherdomain.com`. They assume it's just a different way to write `include`. This assumption is wrong, and it’s the kind of subtle misunderstanding that lets malicious mail slip through or, worse, sends your own legitimate mail to the void.

The `redirect` modifier and the `include` mechanism look similar. They both point to another domain's SPF policy. But how a receiving mail server processes them is fundamentally different. One is a conditional jump that returns. The other is a permanent handoff.

Understanding this distinction isn't just academic. It's about knowing who truly holds the keys to your domain's sending authority. Get it wrong, and you either lose control or create SPF records that fail with a `PermError` before they're even fully evaluated.

The RFC 7208 Processing Model: Subroutine vs. Handoff

The entire debate comes down to a few critical lines in RFC 7208. When a mail transfer agent (MTA) starts an SPF check, it fetches the DNS TXT record from the `MAIL FROM` domain. What it does next depends entirely on the directives it finds. The logic diverges sharply between `include` and `redirect`.

The `include` Mechanism: A Subroutine Call

Think of `include` as a function call in a script. The receiver encounters `include:sendgrid.net`, pauses evaluation of the current record, and recursively starts a new SPF evaluation on `sendgrid.net`. It's looking for a match there. If the SendGrid check returns a `pass`, the whole process stops and the final result is `pass`. Great.

But what if the SendGrid check *doesn't* produce a match? Specifically, if it returns `neutral`, `softfail`, or `fail` (or no result at all, which is treated as `neutral`), the receiver doesn't just give up. It *returns* to the original SPF record right where it left off and continues processing the next mechanism. This is why your `~all` or `-all` at the end of the record is so important; it's the final catch-all after all `include`s have had their say and failed to produce a definitive `pass`.

The `redirect` Modifier: A Terminal Handover

The `redirect` is a different beast entirely. It's not a subroutine; it's a `GOTO`. When a receiver sees `redirect=_spf.google.com`, it effectively discards the rest of the original record. The current evaluation is abandoned. The final result of the *entire SPF check* is now whatever the result of evaluating `_spf.google.com` is. There is no coming back.

If the `_spf.google.com` record check results in `neutral`, the final verdict is `neutral`. If it results in `fail`, the final verdict is `fail`. The original record has zero influence on the outcome from that point forward. It has completely ceded its authority. This is a crucial distinction that most admins miss.

The Real Use Case: Total SPF Delegation

So if `redirect` is so absolute, why use it? It's not for tacking on another marketing email service. That's what `include` is for. The `redirect` modifier is for one primary purpose: complete delegation of SPF policy management.

Imagine Company A acquires Company B. The `company-b.com` domain needs to start sending mail through Company A's infrastructure. The IT team at Company A could try to analyze `company-b.com`'s existing SPF record and merge all its `include`s into their own `company-a.com` policy. This is tedious, error-prone, and creates a massive, brittle SPF record that's likely to exceed the 10-lookup limit.

The clean solution is to replace `company-b.com`'s entire SPF record with one simple line:

v=spf1 redirect=company-a.com

Done. Now, any SPF check for `company-b.com` immediately and permanently defers to the policy at `company-a.com`. Company A's admins can manage a single, centralized SPF record for all their domains. It’s an administrative tool for defining ownership, not a technical tool for adding a sender. This is also common for parent companies managing email for subsidiaries or for complex organizations that centralize all email hygiene services under a single operational team.

Performance Myths and the 10-Lookup Limit

A persistent myth is that `redirect` is more performant than `include` because it saves a DNS lookup. The theory goes that `include:domain.com ~all` requires a lookup for `domain.com` and then might require another action for the `~all`, while `redirect=domain.com` just does one thing. This is a misunderstanding of how the process works.

Both `include` and `redirect` cost one DNS lookup against their target domain. The real performance metric you should care about is the total number of DNS-querying mechanisms, as defined in RFC 7208, Section 4.6.4. You get a maximum of 10. `a`, `mx`, `ptr`, `exists`, and `include` mechanisms all count towards this limit. And yes, a `redirect` also counts as one lookup in the chain.

The performance bottleneck is never the choice between a single `include` and a single `redirect`. The bottleneck is chain reactions. If your `include` points to a record with more `include`s, those all add to the count. If your `redirect` points to a record with nine `include`s, you've just used up your entire budget. The choice of mechanism doesn't change the math of the lookup limit.

Focus on keeping your total lookup chain short. Flattening includes from third-party services that offer dedicated, static IP ranges is a far more effective optimization than worrying about the marginal processing difference between `include` and `redirect`.

The Classic Configuration Error: `redirect` and `all`

You'll eventually see this in the wild, or maybe even write it yourself by mistake: an SPF record that contains both a `redirect` and an `all` mechanism.

v=spf1 redirect=_spf.acme.com -all

This record is invalid. While RFC 7208 states that any mechanisms appearing after a `redirect` modifier *MUST be ignored*, many receiving MTAs take a stricter approach. They see this as a syntactically malformed record and return a `PermError` (Permanent Error) for the entire SPF check. A `PermError` is often treated by DMARC as a failure, and it's a clear signal that the domain owner has misconfigured their policy.

Logic vs. Syntax

The logic is simple: `redirect` is a terminal statement. It means, "Stop processing this record and use that one over there instead." Placing an `all` mechanism after it is like trying to run code after a `return` statement in a C function. It's unreachable code. It makes no logical sense, because the evaluation will never get to the `-all`.

Because it indicates a fundamental misunderstanding of how `redirect` works, many parsers default to failing the check outright. The fix is simple: if you are using `redirect`, it should be the only mechanism in your record besides the `v=spf1` version tag. The `all` mechanism belongs to the policy you are redirecting *to*, not the one you are redirecting *from*.

A Simple Decision Framework

Forget performance myths. The choice between `include` and `redirect` is strategic. It’s about control. Here’s how to decide.

Use `include` when...

You are adding a specific, third-party service to your sending infrastructure. Think a CRM, a marketing platform, or a support desk SaaS. You are augmenting your existing policy by authorizing this service to send on your behalf. You still own the overall policy. Your record will contain multiple `include` mechanisms and will end with an `all` directive. You are granting permission.

Use `redirect` when...

You are completely handing over SPF policy management to another entity or another domain you control. This is for M&A scenarios, parent/subsidiary domain structures, or when consolidating email security under a single managed service. Your record should contain *only* the `redirect` modifier. You are transferring authority.

The takeaway

The distinction between `include` and `redirect` is a perfect example of why email authentication is so tricky. The syntax is subtle, but the operational impact is massive. Choosing the wrong one either creates a syntactically invalid record that results in a `PermError`, or it creates a policy that doesn't behave the way you expect during an incident investigation.

Don't think of it as a technical choice; think of it as an administrative one. Are you adding a sender, or are you changing who owns the policy? Answering that question tells you exactly which one to use. Tools that visualize the full SPF lookup chain, like MailSleuth.AI, can make spotting a misplaced `redirect` or an over-budget `include` chain trivial, but it all starts with understanding the fundamental difference in control.

#spf#dmarc#email-security#rfc-7208#dns#deliverability
MailSleuth Research
Email Security Team

We dissect phishing campaigns and email infrastructure so you don't have to.