What is SPF?
SPF (Sender Policy Framework) is a DNS-based authorization system that lets domain owners declare which servers are allowed to send mail on their behalf.
How SPF works
When a receiving mail server gets an email claiming to be from user@example.com, it performs a simple check:
- Look up the SPF TXT record for
example.com - Parse the record to extract authorization rules (mechanisms)
- Test if the sending server's IP address matches any of those rules
- Accept, reject, or quarantine the message based on the result
The SPF record is just a TXT record on your domain. Here's a minimal example:
v=spf1 ip4:192.0.2.0 ip4:198.51.100.0 -all
This says: "Version 1 of SPF. Servers at 192.0.2.0 and 198.51.100.0 are authorized to send mail for this domain. Everything else is not." The -all at the end is the "fail" rule—any sender not in the list gets rejected.
SPF mechanisms
An SPF record is built from mechanisms—directives that describe which IPs or servers are authorized. The common ones:
ip4 / ip6
Explicitly list IPv4 or IPv6 addresses (or CIDR ranges). Use this for your own mail servers or static IPs from a vendor.
ip4:192.0.2.10/24 # authorizes any IP in the 192.0.2.x range
include:
Pull in SPF rules from another domain. This is how you reference a vendor's SPF policy. When a receiver sees an include:, they recursively look up that domain's SPF record.
include:sendgrid.net # sendgrid publishes their authorized IPs on sendgrid.net
Each include: counts as one DNS lookup. This is why the 10-lookup limit exists. Adding 5 ESPs (Google Workspace, Microsoft 365, SendGrid, Mailgun, Constant Contact) easily hits the limit.
a / mx
The a mechanism authorizes the A/AAAA record of your domain (your mail server). The mx mechanism authorizes the mail exchange servers in your MX records.
a # mail from mail.example.com is okay mx # mail from any of our MX servers is okay
These are convenient for small deployments but can add lookups if your MX or A records resolve to many addresses.
ptr
The ptr mechanism checks the reverse DNS (PTR record) of the sender's IP. It's the least secure mechanism (PTR records are not authoritative) and is deprecated. Avoid it.
exists:
A macro-based mechanism that allows dynamic lookups. Rarely used in simple deployments, but essential for sophisticated policies. Each exists: counts as a lookup.
Qualifiers: pass, soft fail, neutral, fail
Every mechanism can be prefixed with a qualifier that determines the result if the mechanism matches:
| Qualifier | Symbol | Meaning | Common use |
|---|---|---|---|
| Pass | + |
IP is authorized (default if no qualifier) | Most mechanisms |
| Soft fail | ~ |
IP is probably not authorized, but don't reject | Testing, temporary issues |
| Neutral | ? |
No statement about authorization (NXDOMAIN-like) | Rarely used |
| Fail | - |
IP is explicitly not authorized; receiver should reject | The all mechanism: `-all` |
The -all rule at the end of most records is the "fail all" rule—anything not explicitly authorized is rejected. Some organizations use ~all (soft fail) during rollout.
Example SPF records
Simple: single mail provider
v=spf1 include:google.com -all
This says: "Only Google's mail servers (via their published SPF) are authorized to send mail for this domain."
Multiple vendors
v=spf1 include:google.com include:sendgrid.net include:mailgun.org a mx -all
This authorizes Google Workspace, SendGrid, and Mailgun, plus your own A and MX records. That's 3 includes + 2 mechanisms = 5 lookups. Still under the 10-lookup limit, but adding more vendors will push you over.
Using macros for per-IP synthesis
v=spf1 include:%{ir}.%{v}.%{d}.spf.uglydmarc.com -all
This is UglyDMARC's synthetic approach. The macros expand so that each sender's IP is embedded in the query, and our authoritative DNS service answers with a pre-flattened CIDR set. No matter how many vendors you add, it's always one include and a single-IP response.
SPF alignment
SPF passes if the sending server's IP is in the authorized list. But for DMARC (which we'll cover later), there's an additional concept: alignment.
A mail server's Return-Path (the "envelope from" address) might be different from the From header (what users see). SPF alignment asks: does the Return-Path domain match the From domain, or at least share the same organizational domain?
For example, if the From header says alice@example.com but the Return-Path is bounce@mail.example.com, alignment fails unless the SPF record explicitly authorizes mail from mail.example.com or the subdomain relaxes the check.
Common SPF mistakes
Multiple SPF records (only one is used)
DNS TXT records are flat. If you accidentally create multiple TXT records with SPF syntax, only the first one is used. All mechanisms must go in a single record.
Warning
Never create multiple v=spf1 records. Merge all mechanisms into one.
Hitting the 10-lookup limit
Each include:`, `a`, `mx`, and `exists:` mechanism triggers a DNS lookup. The RFC 7208 limit is hard: more than 10 lookups causes a permerror, and SPF evaluation fails. This is the single biggest pain point with SPF and why solutions like UglyDMARC exist.
Using ptr (deprecated and insecure)
PTR records are not authoritative, and attackers can set PTR records pointing to domains they don't own. Never rely on ptr: for authorization.
Forgetting to publish an SPF record
If your domain has no SPF record, receivers treat it as a "neutral" result—mail might still be accepted, but there's no proof of authorization. For critical domains, an explicit policy is essential.
When SPF fails
SPF evaluation can result in several outcomes:
- Pass: The sender's IP matches an authorized mechanism. Mail should be accepted.
- Fail: The sender's IP matches the `-all` rule or a fail mechanism. Receiver should reject.
- Soft fail: The sender's IP matches a `~all` rule. Receiver should accept but flag as suspicious.
- Neutral: No SPF record found, or the result is `?all`. Receiver has no guidance.
- Permerror: The SPF record is malformed or requires more than 10 DNS lookups. Mail is treated as failing.
- Temperror: A temporary DNS lookup failure. Receiver should retry later.
The permerror (too many lookups) is the most insidious: your legitimate mail fails silently, and you won't know why unless you run a manual SPF check.
Going further
SPF is foundational, but it's not bulletproof. It can't prevent a compromised authorized server from sending phishing mail, and the 10-lookup limit breaks at scale. That's where DKIM and DMARC come in.
If you're hitting the lookup limit or managing many vendors, read about the 10-lookup problem and how to solve it. Or jump to DKIM to add cryptographic signing.