SPF — Sender Policy Framework
A DNS TXT record that authorizes which mail servers are permitted to send email on behalf of your domain — the first line of defense against email spoofing.
Publishing a Sender Allowlist in DNS
SPF works by publishing a TXT record at your domain's apex (e.g., example.com IN TXT "v=spf1 ..."). When a receiving mail server gets a message claiming to be from @example.com, it looks up that TXT record and checks whether the sending server's IP is authorized.
SPF checks the envelope From address (also called MAIL FROM or return-path) — not the header From that users see in their email client. This distinction matters: SPF passes even if the visible From header is spoofed to a different domain, which is why DMARC alignment is required to close that gap.
The result is one of: pass, fail, softfail, neutral, none (no SPF record), temperror, or permerror. Receiving servers use this result — along with DKIM and DMARC — to decide whether to accept, quarantine, or reject the message.
SPF Mechanisms and Modifiers
Each mechanism in an SPF record specifies a way to authorize sending IPs
| Mechanism | Example | Description |
|---|---|---|
| ip4 | ip4:203.0.113.0/24 | Authorize an IPv4 address or CIDR range. Most explicit and recommended for known sending IPs. |
| ip6 | ip6:2001:db8::/32 | Authorize an IPv6 address or CIDR range. |
| a | a:mail.example.com | Authorize the A/AAAA record(s) of the given hostname (or the domain itself if omitted). Counts as 1 DNS lookup. |
| mx | mx:example.com | Authorize the IP(s) of the domain's MX records. Common but costs multiple lookups (1 for MX + 1 per MX host). |
| include | include:spf.mailgun.org | Recursively evaluate the SPF record of another domain. Used to authorize third-party senders (ESPs, CRMs). Each include costs at least 1 lookup. |
| redirect | redirect=spf.example.com | Modifier: replace the entire SPF evaluation with another domain's record. Unlike include, the result replaces — not merges — the policy. |
| exists | exists:%{i}.spf.example.com | Perform a DNS lookup for a dynamically constructed domain (using macros). Used for complex per-IP authorization logic. |
| all | -all / ~all / ?all | Catch-all at the end. -all = hard fail, ~all = softfail, +all = pass everything (dangerous), ?all = neutral. |
The 10 DNS Lookup Limit
RFC 7208 limits SPF evaluation to 10 DNS lookups. Each include:, a:, mx:, and exists: mechanism costs at least one lookup. Nested includes count recursively. Exceeding 10 lookups causes a permerror — the SPF record permanently fails, and many receiving servers treat this the same as SPF fail.
Organizations that use many ESPs (email service providers), CRMs, and marketing platforms commonly exceed this limit. Solutions include SPF flattening — replacing include: mechanisms with the resolved IP ranges — or using a managed SPF service that dynamically serves a flattened record.
ip4:andip6:cost zero lookups — always prefer these for known static IPs- Each
include:may nest further includes — count all recursively - SPF flattening must be re-run when the ESP changes their IP ranges
- Tools: MXToolbox, dmarcian, PowerSPF for lookup counting and flattening
- PTR mechanism is explicitly deprecated — do not use it
SPF and Email Forwarding
Email forwarding breaks SPF. When a message is forwarded by an intermediate server (e.g., a university alias, a mailing list, or an old address redirect), the forwarding server's IP is not in the original sender's SPF record. The receiving server sees the forwarding server's IP — which fails SPF for the original sender's domain.
Sender Rewriting Scheme (SRS) addresses this by rewriting the envelope From address when forwarding. The rewritten address uses the forwarding domain, which passes SPF. DMARC sees the forwarded message as failing SPF alignment — but DKIM alignment (which survives forwarding) can carry DMARC on its own.
This is one reason DKIM + DMARC together are more robust than SPF alone: DKIM signatures survive forwarding (as long as the forwarder doesn't modify the message body), while SPF always breaks.
- Sender:
user@company.com - Forwarded by:
alias@university.edu - Received by:
inbox@gmail.com
Gmail checks SPF for company.com but sees university.edu's IP → SPF fail. DKIM from company.com still validates → DMARC passes via DKIM alignment.