Sender Policy Framework (SPF, RFC 7208) is the oldest of the three pillars of email authentication. It is a DNS-based mechanism that lets you declare which servers are allowed to send email on behalf of your domain. This article explains how SPF works, how to read and write an SPF record, what its limitations are, and why no UK business in 2026 should operate an email domain without one.
SPF is a DNS TXT record published at the root of your domain that lists every server authorised to send email using your domain name. When a receiving mail server accepts an incoming SMTP connection, it looks up your SPF record and checks whether the IP address that just connected is listed. If it is, the receiver stamps spf=pass into the Authentication-Results header; if it is not, the receiver stamps spf=fail or spf=softfail.
That is the entire protocol. There is no cryptography, no signing, no negotiation — just a DNS lookup and a comparison of IP addresses. The elegance of SPF is also its limitation: it only checks the envelope sender (the MAIL FROM address), not the From: header users see. That gap is what DMARC exists to close.
Follow a single message being received by Gmail from a Bristol law firm running its own mail server on a SmartXHosting plan:
MAIL FROM:<[email protected]>. This is the envelope sender.firm.co.uk from the envelope sender and performs a DNS TXT lookup for firm.co.uk.v=spf1.pass, fail, softfail or neutral) is written into the Authentication-Results header of the delivered message.The whole check typically completes in under 100 milliseconds. The SPF lookup costs one DNS round-trip for the base record plus more for any include: chains. This is why the 10-lookup limit matters so much in practice.
A real SPF record for a Leeds charity sending mail from its own mail server plus Mailchimp for newsletters looks like this:
charity.org.uk. IN TXT "v=spf1 mx include:servers.mcsv.net -all"Breaking it down token by token:
v=spf1 — version identifier. Must be the first token. Identifies this TXT record as an SPF policy. Only spf1 is current; there is no spf2.mx — authorises the IP addresses returned for the domain's MX records. Costs one DNS lookup.include:servers.mcsv.net — authorises everything listed in Mailchimp's SPF record (their sending infrastructure). Costs one lookup plus however many lookups are needed to resolve the included policy.-all — hard fail. Any IP not matched by the previous mechanisms is explicitly not authorised; receivers should reject.The order matters. Mechanisms are evaluated left-to-right and the first match wins.
SPF defines nine mechanisms. The five you will actually use day-to-day:
| Mechanism | Matches when | Lookup cost |
|---|---|---|
ip4:203.0.113.0/24 | Sending IP is in the specified IPv4 range | 0 |
ip6:2001:db8::/32 | Sending IP is in the specified IPv6 range | 0 |
a or a:hostname | Sending IP matches the A record of the domain or hostname | 1 |
mx or mx:hostname | Sending IP is listed in the MX records | 1+ |
include:domain.com | Sending IP matches another domain's SPF policy | 1+ |
Four mechanisms are rarely used in 2026 and should usually be avoided:
ptr — evaluate against reverse DNS. RFC 7208 recommends against using this mechanism because it is slow and unreliable. Do not publish ptr in new records.exists:domain.com — matches if an A record exists for the given domain. Specialised use case.all — the universal match. Always used with a qualifier (see below) as the final mechanism.redirect=domain.com — replaces the entire record with the one at domain.com. Counts as a lookup.Every mechanism carries an implicit or explicit qualifier that determines the result when it matches:
| Qualifier | Result | Header | What receivers should do |
|---|---|---|---|
+ (default) | Pass | spf=pass | Accept the message |
- | Fail (hard) | spf=fail | Reject the message |
~ | SoftFail | spf=softfail | Accept but mark as suspicious |
? | Neutral | spf=neutral | No opinion — usually treat as if no SPF exists |
In production, the only qualifiers you should use on the final all mechanism are -all or ~all. The choice is a trade-off:
-all (hard fail). The strongest posture. Forces receivers to reject unauthorised senders. Required for DMARC enforcement to be meaningful.~all (soft fail). A safer posture during initial deployment. Failing messages still reach the inbox but are tagged. Use for the first few weeks, then upgrade to -all once the sender landscape is fully mapped.+all (accept all). Destroys the point of SPF entirely. Never publish this.?all (neutral all). Equivalent to having no SPF. Almost never appropriate.The process for a typical UK SME:
mx or an ip4: range.v=spf1, add one mechanism per sender, finish with ~all (during initial deployment) or -all (at steady state).check-auth verifier. If you exceed 10 lookups, flatten the record (replace include: with explicit ip4: ranges).A completed SPF for a Manchester accountancy firm using on-premises mail plus Microsoft 365 for staff and Mailchimp for marketing:
accountants.co.uk. IN TXT "v=spf1 mx include:spf.protection.outlook.com include:servers.mcsv.net -all"SPF is a useful but limited protocol. Understanding its limits is what keeps you from over-investing in it or under-investing in the rest of the stack:
RFC 7208 Section 4.6.4 caps SPF evaluation at 10 DNS lookups. Each include:, a, mx, exists:, redirect= and ptr mechanism counts. Nested includes (an include that itself contains includes) add to the total. Exceeding the limit produces PermError, which most receivers treat as a failure.
When a message is forwarded — by a mailing list, a university gateway, or a personal forwarding rule — the sending IP changes to the forwarder's server. That IP is not listed in the original domain's SPF record, so SPF fails. This is not a bug; it is a consequence of how SPF is designed. ARC was created to paper over this failure mode.
The MAIL FROM address can be different from the From: header the recipient sees. An attacker can send a message with From: [email protected] while using a different envelope sender domain that has its own perfectly valid SPF record. SPF alone gives no protection against that. DMARC's alignment requirement closes this gap.
SPF only looks at the sending IP. It has no mechanism to detect whether the message body was modified in transit. DKIM is the protocol that fills that gap.
SPF began life as "Sender Permitted From" in 2003, a parallel effort to Microsoft's "Caller ID for Email". The two proposals merged into Sender ID in 2004, but the merged specification failed to reach consensus and SPF split back out as a separate RFC. RFC 4408 was published in 2006 as an experimental standard, and RFC 7208 upgraded it to Proposed Standard in 2014.
A key historical footnote: RFC 4408 permitted SPF records to be published using either the TXT or the new SPF DNS record type. RFC 7208 deprecated the SPF record type entirely in favour of TXT. If you still have an RR type 99 "SPF" record from 2008 in your DNS, delete it.
A new SPF deployment on a UK business domain typically looks like this:
v=spf1 mx include:spf.protection.outlook.com include:servers.mcsv.net include:_spf.smartxhosting.uk ~all.spfcheck command-line tool. Confirm under 10 lookups.~all to -all. SPF now enforces hard-fail on unauthorised senders.This timeline is conservative; an experienced team can compress the whole thing into a week if the sender landscape is simple.
SPF is explicitly required or strongly recommended by multiple UK frameworks:
-all or ~all.Mailing lists are one of the classic places where SPF behaves counter-intuitively. When a user sends a message to [email protected], the list server accepts the message, sometimes modifies it (adds a subject prefix, a footer with unsubscribe information, and mailing-list headers), and then redistributes it to subscribers. The redistribution uses the list server's IP as the sending IP. For every subscriber's receiving mail server, that IP is not listed in the original sender's SPF record.
Three approaches are used by modern UK list operators:
From: header to an address on the list's own domain, re-signs with its own DKIM, and publishes SPF for the list domain. The original sender's domain is preserved in a Reply-To header. This is the Mailman 3 default and what most UK professional bodies now use.Most large providers maintain their own SPF macros that you include: rather than listing IPs manually. A few to be aware of:
| Provider | Include | Notes |
|---|---|---|
| Microsoft 365 | spf.protection.outlook.com | Expands to around five IPv4 and five IPv6 ranges; counts as roughly two lookups once fully resolved. |
| Google Workspace | _spf.google.com | Heavily nested include chain — consumes up to four lookups on its own. |
| SendGrid | sendgrid.net | Flat include, one lookup. |
| Mailgun | mailgun.org | Regional variants exist — check the exact string your Mailgun account provides. |
| Amazon SES | amazonses.com | Different regions use the same include but different underlying ranges. |
| Mailchimp | servers.mcsv.net | Flat, single lookup. |
| HubSpot | hubspotemail.net | Maintained per HubSpot account; do not hard-code IPs. |
For domains with many includes, flattening to explicit ip4: ranges is the standard remediation — but flattening means you must periodically re-flatten as the upstream provider changes their addresses. Most UK teams use a flattening service rather than maintaining static IP lists by hand.
ptr mechanism. Deprecated by RFC 7208. Remove it.-all. A record that ends v=spf1 include:... with no all mechanism is treated as if +all were present — SPF becomes meaningless. Always terminate with -all or ~all.From: are different organisational domains — in which case DMARC fails. Always verify end-to-end.v=spf1 ip4:217.149.241.18 ~all. Pair that with a DMARC record at p=reject; aspf=s; adkim=s and the domain is effectively unspoofable. A Business Email or Private Email plan ships with SPF, DKIM and DMARC pre-configured for your domain.
Q: Can a domain have more than one SPF record?
A: No. Publishing two SPF TXT records on the same domain causes a PermError on the receiver side. All SPF tokens must be combined into a single record.
Q: Do I need SPF if I have DKIM and DMARC?
A: Yes. DMARC passes if either SPF or DKIM aligns — and you need every possible pathway to pass, especially when dealing with the various edge cases of mailing lists and forwarders. Omit SPF and you lose redundancy.
Q: What happens if a recipient rejects my mail because of SPF fail?
A: The receiving server returns an SMTP 550 response and your sending server generates a non-delivery report back to the envelope sender. To fix the problem, find the sender that was missed and add its IP or include: mechanism to your SPF.
Q: How do I find out why SPF failed for a particular message?
A: Look at the Authentication-Results header of the delivered message (or the SMTP response if the message was rejected). The header shows the envelope sender domain, the sending IP, and the SPF result with a reason string.
Q: Is ~all permanent or a stepping stone?
A: A stepping stone. Start with ~all during initial deployment to avoid blocking legitimate mail from senders you may have missed. Once DMARC aggregate reports confirm all your legitimate senders pass, upgrade to -all.
Q: Can I use SPF without DMARC?
A: Technically yes, but you lose most of the benefit. Without DMARC, receivers have no policy instruction when SPF fails, and you have no visibility into spoofing attempts. Publish both.
Q: How often should I review my SPF record?
A: Quarterly for a small business; monthly for a larger operation with many SaaS integrations. Any time you onboard a new email-sending service, update SPF immediately — before the service starts sending.
Q: Does SPF work for inbound mail?
A: No. SPF is published by the sending domain for receivers to check. For inbound filtering of messages claiming to come from external domains, you rely on the external domain's own SPF record, which your mail server evaluates on receipt.
Q: Can SPF protect me from a spammer using a spoofed From: header?
A: Only indirectly. SPF alone does not protect the visible From: header. DMARC alignment is what stops spoofed From: headers, and DMARC relies on SPF or DKIM to provide the underlying authentication.
Q: My domain has no mail flow. Do I still need SPF?
A: Yes, and use a null SPF: v=spf1 -all. This tells receivers that no IP should ever send for this domain — any message claiming to come from it should be rejected. Pair it with DMARC p=reject and a null DKIM for full non-sending-domain protection.
Q: Is SPF checked before or after the message body is received?
A: SPF is checked during the SMTP conversation, immediately after the MAIL FROM command and before the message data (DATA) is transferred. A hard-fail result allows the receiver to reject the message before even accepting the body, saving bandwidth. This is one of the practical advantages of SPF over DKIM, which requires the full message to be received before verification can complete.
Q: Do I need to publish separate SPF records for my marketing subdomain (email.firm.co.uk) and my main domain (firm.co.uk)?
A: Yes, if both subdomains actually send email. SPF is not inherited from the parent domain. Publishing SPF at firm.co.uk has no effect on mail sent from email.firm.co.uk. If the subdomain never sends, a null SPF (v=spf1 -all) on it is a defence-in-depth measure worth taking.