Skip to content
Authentication

SPF mechanisms: ip4, ip6, a, mx, include, exists, ptr, all

The eight SPF mechanisms decide which servers match a record. What each one tests, what it costs in DNS lookups, and when to use or avoid it.

Mechanisms are the matching directives of an SPF record: each one tests the connecting server's IP address in a specific way, and the first mechanism that matches ends the evaluation with its qualifier's result. RFC 7208 defines eight. Two of them cost nothing to evaluate, five consume the 10-lookup DNS budget, and one is deprecated. Choosing the right ones is most of SPF record design.

The zero-cost mechanisms: ip4 and ip6

ip4 and ip6 match the connecting IP against a literal address or CIDR range: ip4:198.51.100.7 for a single host, ip4:198.51.100.0/24 for a block, ip6:2001:db8::/32 for IPv6 space. They trigger no DNS lookups, evaluate instantly, and cannot break when someone else's infrastructure changes. For servers you operate and whose addresses you control, literal IP mechanisms are the most robust choice available.

Their weakness is the flip side: the record is only as current as your last edit. Renumbering the MTA fleet without updating the record silently deauthorizes your own mail. IP mechanisms suit stable, self-operated infrastructure, and suit rented, vendor-managed address space poorly.

The delegation mechanism: include

include:otherdomain.com evaluates the other domain's SPF record and matches if that evaluation returns pass. It is how vendors publish their sending infrastructure once and let every customer reference it: include:_spf.google.com, include:sendgrid.net. The vendor updates their record when their fleet changes, and your record follows automatically.

The convenience mechanisms: a and mx

a matches if the connecting IP appears in the A or AAAA records of the domain (or a named argument: a:mail.example.com). mx matches if the IP belongs to any of the domain's MX hosts. Both cost DNS lookups: one for a, and for mx one lookup for the MX set plus one per MX hostname resolved, which makes mx surprisingly expensive.

Both mechanisms encode an assumption that is frequently false: that the machines serving your website or receiving your mail are also the machines sending it. In modern setups with separate outbound infrastructure, a and mx authorize hosts that never send and miss the ones that do. Prefer explicit ip4 ranges or vendor includes, and use a and mx only where the assumption genuinely holds.

The specialist: exists

exists:domain matches if the named domain resolves to any A record, and its power comes from macro expansion: exists:%{i}.allow.example.com constructs a per-IP hostname and effectively turns DNS itself into an authorization database. Large infrastructure operators use it for fine-grained, dynamically managed authorization. For typical senders it is rarely needed, and records containing macros deserve careful review because few humans read them correctly at a glance.

The deprecated one: ptr

ptr matches by reverse-resolving the connecting IP and checking the resulting hostname, a design that is slow, unreliable, and abusable. RFC 7208 explicitly discourages it, some receivers skip it entirely, and its lookups count doubly painfully against the budget. Any record still containing ptr should be edited today; whatever it authorizes can be expressed with ip4 or include.

The mandatory terminator: all

all matches every IP unconditionally, which is why it stands last and defines what happens to mail from servers nothing else matched. Its meaning comes entirely from its qualifier: -all fails unauthorized senders, ~all softfails them, ?all shrugs. A record without an all (or a redirect) leaves unmatched senders at an implicit neutral, which defeats the point of publishing a record. Every production SPF record should end in an explicit all.

Mechanism reference

FeatureMatches whenDNS lookup cost
ip4 / ip6IP is in the literal range0
includeIncluded record returns pass1 + nested lookups
aIP is in the domain's A/AAAA records1
mxIP belongs to a domain MX host1 + 1 per MX host
existsConstructed name resolves1
ptr (deprecated)Reverse DNS name validatesexpensive, avoid
allAlways0

The lookup costs in the table are the currency of the 10 DNS lookup limit, and mechanism choice is the main way records stay inside it. For how mechanisms combine into a full record, see the record syntax entry.

Frequently asked questions

Which mechanisms should a typical sender use?
Literal ip4/ip6 ranges for self-operated MTAs, one include per active sending vendor, and an explicit all terminator with a strict qualifier. Most production records need nothing else.
Can I nest includes inside includes?
Yes, and vendors do: their published record often includes further internal records. Nesting works transparently, but every level spends lookups from your budget, which is why a single vendor include can cost four or five lookups.
Does include:domain also authorize mail claiming to be from that domain?
No. include only borrows the other domain's list of IPs for evaluating your domain's mail. It grants no rights in the other direction and does not affect the other domain at all.
What does a mechanism argument like ip4:198.51.100.0/24 mean exactly?
CIDR notation: the /24 covers all 256 addresses from 198.51.100.0 to 198.51.100.255. Without a suffix, a single address is meant. Overly broad ranges authorize more infrastructure than you control, so scope them tightly.

Key takeaways

  • ip4 and ip6 are free to evaluate and ideal for infrastructure you control; include delegates to vendors at a lookup cost
  • a and mx assume web or inbound hosts also send mail, an assumption that is usually false in modern setups
  • exists with macros is powerful for large operators and overkill for typical senders
  • ptr is deprecated: remove it from any record that still carries it
  • Every record ends with an explicit all whose qualifier defines the fate of unauthorized mail