SPF explained: lookups, includes and all

Updated 2026-10-08

Sender Policy Framework (SPF) lets a domain publish which hosts may send mail using that domain in the SMTP envelope. A receiving server compares the connecting IP address with the published policy and gets a result such as pass, fail, softfail, neutral, none, temperror or permerror. The specification is RFC 7208.

What SPF checks

SPF evaluates the domain of the envelope sender, the address given in the SMTP MAIL FROM command, and the name given in HELO or EHLO. It does not look at the From header that mail clients display. A message can pass SPF for one domain and show a completely different domain to the reader. Linking the two is the job of DMARC; see DMARC explained.

The policy is a single TXT record at the domain name that starts with v=spf1. The dedicated SPF record type was discontinued by RFC 7208, so only TXT is used.

Syntax and mechanisms

A record is a version tag followed by space-separated terms, evaluated from left to right. The first term that matches decides the result.

Term Matches
ip4:192.0.2.0/24, ip6:2001:db8::/32 The connecting IP is inside the network.
a, a:host.example The connecting IP is one of the address records of the name.
mx The connecting IP is one of the addresses of the domain's mail exchangers.
include:other.example The policy of the other domain evaluates to pass.
exists:name.example The name resolves to any A record.
ptr A reverse-lookup based match. RFC 7208 section 5.5 says it SHOULD NOT be published.
all Always matches. It belongs at the end.

redirect=other.example is a modifier, not a mechanism. It is explained below.

Qualifiers and all

Each mechanism can carry a qualifier that sets the result when it matches: + for pass (the default when no qualifier is written), - for fail, ~ for softfail and ? for neutral. A record that ends with -all says that everything not listed fails. ~all says softfail. ?all says nothing is asserted. +all authorises every sender on the internet and makes the record useless as a protection.

If no term matches and the record has no redirect, the result is neutral (RFC 7208 section 4.7). A record with no all therefore asserts nothing about unlisted senders.

The lookup limits

To keep evaluation cheap for receivers, RFC 7208 section 4.6.4 limits the number of terms that cause DNS queries. The terms that count are include, a, mx, ptr, exists and the redirect modifier. ip4, ip6 and all do not count. The limit is ten per evaluation, and it covers the whole tree: an include costs one lookup plus every lookup inside the included record. Exceeding it is a permerror.

The same section also says that more than two "void" lookups, lookups that return no data (an empty answer or a name that does not exist), produce a permerror. Void lookups usually point to a stale include or a typo.

What the SPF check does with this:

  • It counts the lookup-causing terms across the include and redirect tree and reports the total against the limit of ten (SPF_TOO_MANY_LOOKUPS).
  • It resolves only include and redirect targets. The a, mx and exists terms are counted but not resolved, so void lookups are counted for include and redirect targets only (SPF_TOO_MANY_VOID_LOOKUPS). A real receiver may see more void lookups than the check reports.
  • It does not evaluate the policy for a particular sender IP address.

include and redirect

include: asks whether another domain's policy passes for the same sender. If the included policy returns pass, the include term matches. If it returns fail, softfail or neutral, the term does not match and evaluation continues with the next term. If the included domain has no SPF record, the result is permerror (RFC 7208 section 5.2); see SPF_INCLUDE_NOT_FOUND. The qualifier on the include term is applied only when the included policy passes.

redirect= hands the whole decision to another domain, and only if no mechanism in the current record matched. The result of the other domain's policy becomes the result, including its all. If the record contains an all mechanism, the redirect modifier is ignored (RFC 7208 section 6.1). A redirect to a name without an SPF record is a permerror.

Use include to add a third-party sender to your own policy. Use redirect when many domains should share one policy.

Common mistakes

Reducing lookups

  • Remove includes for services you no longer use.
  • Replace a and mx terms by ip4 and ip6 terms where the addresses are stable. These cost no lookups, but they must be kept up to date.
  • Send different kinds of mail from different subdomains, each with its own short record, instead of putting every provider into the record of the main domain.
  • Be careful with "flattening" tools that replace includes by address lists. They remove the lookups but also freeze addresses that the provider may change.

SPF and DMARC

DMARC passes on SPF only when the SPF result is pass and the domain that was checked is aligned with the From domain. Forwarded mail usually fails SPF, because the forwarder's IP address is not in the original policy; DKIM signatures normally survive forwarding. This is why DMARC accepts either of the two.

To inspect a domain, use the SPF check, or the mail check for SPF, DMARC, DKIM and MX in one report.

SPF findings

Frequently asked questions

What happens when an SPF record needs more than ten DNS lookups?

RFC 7208 section 4.6.4 says evaluation must stop with a permanent error (permerror). What a receiver then does with the message is its own policy, but the SPF result cannot count as a pass. The SPF check reports this as SPF_TOO_MANY_LOOKUPS.

Does a domain need more than one SPF record?

No, and it must not publish more than one. If a name has several TXT records that start with v=spf1, evaluation ends with permerror (RFC 7208 section 4.5). Merge the records into one.

Should I use -all or ~all?

-all asks receivers to treat unlisted senders as a failure and ~all as a softfail. Both are valid. Use -all once you are confident that every system that sends mail with your domain in the envelope sender is listed. DMARC is what turns the result into a policy decision for the visible From domain.

Does SPF protect the From address people see?

Not by itself. SPF checks the domain in the envelope sender (and, when that is empty, the HELO name). The From header is covered only when DMARC requires the SPF domain to align with it.