Loading learning content...
When email was designed in the early 1980s, the internet was a trusted academic network where everyone knew everyone. The SMTP protocol was built with no authentication mechanism—any server could claim to send mail on behalf of any domain. This design decision haunts us to this day.
The 'From' address in an email is as trustworthy as the return address on a physical envelope—which is to say, not trustworthy at all. Anyone can write any address. This fundamental flaw enabled the phishing and spoofing attacks we examined in the previous page.
Sender Policy Framework (SPF) is the first major protocol designed to close this gap. It provides a mechanism for domain owners to declare which IP addresses are authorized to send email on their behalf, and for receiving mail servers to verify those declarations.
Published as RFC 7208 (2014), SPF is now deployed by over 90% of email-sending domains worldwide. Understanding SPF is essential for every network engineer, as it forms the foundation upon which DKIM and DMARC build their more sophisticated protections.
By the end of this page, you will understand SPF's design philosophy, DNS record syntax, validation mechanisms, failure modes, and integration with the broader email authentication ecosystem. You'll be able to construct, interpret, and troubleshoot SPF records for any domain.
To understand SPF, we must first understand the email spoofing problem it addresses.
SMTP has multiple places where sender identity appears, and none are verified by the protocol itself:
1. Envelope Sender (MAIL FROM / Return-Path) The address used in the SMTP 'MAIL FROM' command during message transmission. This is where bounce messages are sent. It's invisible to most email clients.
2. Header From The 'From:' line visible to the recipient in their email client. This is what users see and trust.
3. Reply-To The optional address that receives replies. Often different from the From address.
The critical vulnerability: all of these can be set to any value the sender chooses. SMTP neither validates nor enforces any relationship between them.
1234567891011121314151617181920
# An attacker connecting from IP 198.51.100.50 can send this: HELO malicious-server.comMAIL FROM:<ceo@legitimate-bank.com> ← Envelope sender (spoofed)RCPT TO:<victim@target.com>DATAFrom: John Smith <ceo@legitimate-bank.com> ← Display address (spoofed)To: victim@target.comSubject: Urgent: Verify Your Account Dear Customer, Please click here to verify your account immediately... .QUIT # Without SPF, the receiving server has NO WAY to know that # legitimate-bank.com didn't authorize IP 198.51.100.50 to send email.# The victim sees "ceo@legitimate-bank.com" and trusts it.The fundamental problem: receivers cannot verify senders. Before SPF, a receiving mail server had no standardized way to check whether an IP address was actually authorized to send mail claiming to be from a particular domain. SPF solves this specific problem—validating IP authorization for the envelope sender.
SPF operates on a beautifully simple principle: domain owners publish authorized sending IP addresses in DNS, and receivers verify incoming mail against those records.
Step 1: Domain Owner Publishes SPF Record The domain owner creates a TXT record in DNS specifying which IP addresses, networks, and third-party services are authorized to send email for their domain.
Step 2: Sender Transmits Email An email is sent from some IP address with an envelope sender (MAIL FROM) claiming to be from the domain.
Step 3: Receiver Extracts Domain The receiving mail server extracts the domain from the envelope sender address (e.g., 'example.com' from 'user@example.com').
Step 4: Receiver Queries DNS The receiver looks up the SPF record for that domain (TXT record starting with 'v=spf1').
Step 5: Receiver Evaluates Policy The receiver checks whether the connecting IP address matches any authorized sender in the SPF record.
Step 6: Receiver Takes Action Based on the SPF result (pass, fail, soft fail, neutral, etc.), the receiver takes appropriate action.
DNS-Based Publication SPF leverages DNS because:
Envelope Sender Focus SPF validates the envelope sender (MAIL FROM), not the header From. This design choice was deliberate:
IP-Based Authorization SPF operates at the IP level, not cryptographic identity. This means:
SPF records are published as DNS TXT records with a specific syntax defined in RFC 7208. Understanding this syntax enables you to construct records for any organization and interpret records you encounter.
An SPF record consists of:
v=spf1redirect=, exp=)| Mechanism | Syntax | Description | Example |
|---|---|---|---|
all | all | Matches all IPs (catch-all) | -all (fail all others) |
ip4 | ip4:<addr> or ip4:<network>/<cidr> | IPv4 address or network | ip4:192.0.2.10 or ip4:192.0.2.0/24 |
ip6 | ip6:<addr> or ip6:<network>/<cidr> | IPv6 address or network | ip6:2001:db8::1/128 |
a | a or a:<domain> | A record IP(s) of domain | a:mail.example.com |
mx | mx or mx:<domain> | MX record IP(s) of domain | mx (own MXes authorized) |
include | include:<domain> | Include another domain's SPF | include:_spf.google.com |
exists | exists:<domain> | True if domain resolves | exists:%{i}._spf.example.com |
redirect | redirect=<domain> | Use another domain's SPF entirely | redirect=_spf.example.com |
Each mechanism can be prefixed with a qualifier that determines the result if it matches:
| Qualifier | Meaning | Result | Recommended Action |
|---|---|---|---|
+ (Pass) | Explicitly authorized | Pass | Accept message |
- (Fail) | Explicitly unauthorized | Fail | Reject message |
~ (SoftFail) | Probably unauthorized | SoftFail | Accept but mark/flag |
? (Neutral) | No assertion | Neutral | Process as if no SPF |
123456789101112131415161718192021222324
# Example 1: Simple single-server domainexample.com. IN TXT "v=spf1 ip4:192.0.2.10 -all"# Meaning: Only IP 192.0.2.10 is authorized. Fail all others. # Example 2: Multiple authorized sourcesexample.com. IN TXT "v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.50 mx -all"# Meaning: The /24 network, one specific IP, and MX servers are authorized. # Example 3: Using third-party email servicesexample.com. IN TXT "v=spf1 include:_spf.google.com include:amazonses.com -all"# Meaning: Google Workspace and Amazon SES are authorized (their SPF included). # Example 4: Corporate with multiple providersexample.com. IN TXT "v=spf1 mx a:mail.example.com include:_spf.google.com include:spf.protection.outlook.com ip4:203.0.113.0/24 -all"# Meaning: MX servers, mail.example.com A record, Google, Microsoft 365, and a /24 are authorized. # Example 5: Soft fail during testing/migrationexample.com. IN TXT "v=spf1 include:_spf.google.com ~all"# Meaning: Google authorized, others soft fail (monitor but don't reject). # Example 6: Subdomain delegation_spf.example.com. IN TXT "v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.0/24 -all"example.com. IN TXT "v=spf1 redirect=_spf.example.com"# Meaning: Use the _spf subdomain's policy for the main domain.Understanding how SPF records are evaluated is critical for constructing correct records and troubleshooting failures. The evaluation follows a deterministic algorithm defined in RFC 7208.
v=spf1all, result is NeutralCritical constraint: SPF evaluation is limited to 10 DNS lookups that cause new queries. This includes:
include: mechanismsa: mechanisms with domain argumentsmx: mechanisms with domain argumentsredirect= modifiersexists: mechanismsMechanisms that don't count:
ip4: and ip6: (no DNS lookup needed)all (no lookup)a and mx without explicit domain (use current domain, already looked up)Exceeding 10 DNS lookups results in a PermError, which many receivers treat as a failure. This limit exists to prevent denial-of-service attacks via recursive SPF queries. Large organizations using multiple email providers often hit this limit and must restructure their SPF with flattening or sub-delegation.
123456789101112131415161718192021
# Example: Counting DNS lookups in an SPF record example.com TXT "v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:amazonses.com mx a:mail.example.com -all" # Lookup count:# 1. include:_spf.google.com → DNS query → counts as 1# └─ _spf.google.com itself may have includes (chains add up!)# 2. include:spf.protection.outlook.com → counts as 1# └─ Outlook's SPF also has nested includes# 3. include:amazonses.com → counts as 1# 4. mx → counts as 1 (needs MX lookup)# 5. a:mail.example.com → counts as 1 (needs A lookup) # PROBLEM: Google's SPF alone can consume 4-5 lookups!# Full chain often exceeds 10 lookups → PermError # SOLUTION: SPF flattening (convert includes to ip4/ip6 mechanisms)# Flattened version (no include lookups):example.com TXT "v=spf1 ip4:209.85.128.0/17 ip4:64.233.160.0/19 ... ip4:203.0.113.10 -all" # Trade-off: Must update when provider IPs changeSPF evaluation produces one of seven results, each carrying different implications for message handling. Understanding these results is essential for troubleshooting and policy design.
| Result | Meaning | Typical Action | Authentication-Results Header |
|---|---|---|---|
| Pass | IP explicitly authorized | Accept normally | spf=pass |
| Fail | IP explicitly unauthorized (-all) | Reject or quarantine | spf=fail |
| SoftFail | IP probably unauthorized (~all) | Accept but flag/score | spf=softfail |
| Neutral | No policy assertion (?all or no all) | Accept as if no SPF | spf=neutral |
| None | No SPF record exists | Accept as if no SPF | spf=none |
| PermError | Permanent error (syntax, >10 lookups) | Accept but flag as error | spf=permerror |
| TempError | Temporary DNS failure | Defer (try again later) | spf=temperror |
Conservative receivers (most enterprise gateways, Gmail, Microsoft 365):
Liberal receivers (older systems, some ISPs):
DMARC-aware receivers:
123456789101112131415161718192021
# Example Authentication-Results header showing SPF evaluation Authentication-Results: mx.google.com; dkim=pass header.i=@example.com header.s=selector1 header.b=abc123; spf=pass (google.com: domain of user@example.com designates 203.0.113.10 as permitted sender) smtp.mailfrom=user@example.com; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com # Breaking down the SPF portion:# - spf=pass → Result is Pass# - google.com: → Receiver performing the check# - domain of user@example.com → MAIL FROM domain checked# - designates 203.0.113.10 as permitted sender → IP matched SPF record# - smtp.mailfrom=user@example.com → Full envelope sender # Example of SPF failure:Authentication-Results: mx.receiver.com; spf=fail (receiver.com: domain of ceo@bank.com does NOT designate 198.51.100.50 as permitted sender) smtp.mailfrom=ceo@bank.com # This is a spoofing attempt! bank.com didn't authorize 198.51.100.50When deploying SPF, start with ~all (soft fail) rather than -all (hard fail). This allows monitoring of SPF results without breaking legitimate mail flows from previously unknown sources. Once confident that all legitimate senders are covered, switch to -all.
SPF is a powerful tool, but it has inherent limitations that must be understood. These limitations drive the need for complementary technologies like DKIM and DMARC.
Email forwarding is SPF's Achilles' heel. Consider this scenario:
ARC (Authenticated Received Chain): Preserves authentication results through forwarding chains. Allows Gmail to trust that forwarder.edu verified SPF before forwarding.
SRS (Sender Rewriting Scheme): Forwarders rewrite the envelope sender to their own domain, making forwarding SPF-compliant. The original sender is encoded in the new address.
DKIM: Cryptographically signs message content. Signature survives forwarding because it's part of the message, not dependent on sending IP.
DMARC: Bridges SPF and DKIM with alignment requirements, addressing the header From spoofing gap.
SPF alone cannot prevent sophisticated phishing. An attacker can register look-alike-domain.com, set up valid SPF, and send phishing emails that pass SPF. Only combined with DKIM and DMARC does SPF provide robust protection. Think of SPF as one leg of a three-legged stool.
Deploying SPF correctly requires careful planning and methodical execution. Here's a step-by-step approach used by enterprise administrators.
Identify ALL legitimate email sources:
Common oversight: Forgotten systems like development servers, legacy applications, or department-specific tools often cause SPF failures post-deployment.
include:_spf.google.com)1234567891011121314151617181920212223242526272829303132333435363738394041
# Phase 1: Discovery - Example sources for a typical enterprise Corporate Mail: Microsoft 365Marketing: Mailchimp, HubSpot Transactional: SendGridHR System: WorkdaySupport: ZendeskLegacy Apps: On-premise server 203.0.113.50 # Phase 2: Gather provider SPF mechanisms Microsoft 365: include:spf.protection.outlook.comMailchimp: include:servers.mcsv.netHubSpot: include:_spf.hubspot.com SendGrid: include:sendgrid.netZendesk: include:mail.zendesk.comWorkday: (Check Workday documentation for current include) # Phase 3: Count lookups 1. spf.protection.outlook.com → +2-3 nested includes = ~4 total2. servers.mcsv.net → 13. _spf.hubspot.com → 14. sendgrid.net → +1-2 nested = ~3 total5. mail.zendesk.com → 1 PROBLEM: Already at 10+ lookups before adding legacy server! # Phase 4: Solution options Option A: Remove a provider from main record, use subdomainmarketing.example.com TXT "v=spf1 include:servers.mcsv.net include:_spf.hubspot.com -all"example.com TXT "v=spf1 include:spf.protection.outlook.com include:sendgrid.net include:mail.zendesk.com ip4:203.0.113.50 -all" Option B: SPF flattening (resolve includes to IP lists)example.com TXT "v=spf1 ip4:52.100.0.0/16 ip4:40.107.0.0/16 ... -all"# Requires automation to update when provider IPs change Option C: Use redirect for subdomain delegation_spf.example.com TXT "v=spf1 ip4:203.0.113.50 include:spf.protection.outlook.com ..."example.com TXT "v=spf1 redirect=_spf.example.com"SPF provides the foundational layer of email authentication, validating that connecting servers are authorized to send mail for claimed domains. Let's consolidate the key concepts:
~all (soft fail), monitor results, then switch to -all (hard fail) once confident.What's Next:
While SPF verifies the sending IP, it cannot verify message integrity or survive forwarding. The next page covers DKIM (DomainKeys Identified Mail), which uses cryptographic signatures to:
Together, SPF (IP authorization) and DKIM (cryptographic signing) form the inputs that DMARC uses to make enforcement decisions.
You now understand SPF's design, syntax, evaluation process, limitations, and implementation best practices. You can construct SPF records for any organization, troubleshoot SPF failures, and explain why SPF alone isn't sufficient for complete email authentication.