emailr_
All articles
explainer·8 min

What is SPF? Complete guide for developers

authenticationspfdns

Summary

SPF is a DNS record that tells the world which servers can send email for your domain. Without it, you're basically leaving your front door unlocked and wondering why strangers keep walking in.

In 2014, a small e-commerce company woke up to discover that someone had sent 50,000 phishing emails to their customers—all appearing to come from their official domain. The emails looked legitimate. The from address was correct. Customers clicked, entered their credit card details, and the company spent the next six months rebuilding trust they'd spent years earning.

The attack was possible because of a single missing DNS record: SPF.

SPF—Sender Policy Framework—is one of those things that sounds technical and boring until you understand what it actually does. It's the difference between anyone being able to send email as you, and only your authorized servers having that privilege. It's the digital equivalent of a bouncer checking IDs at the door.

The problem SPF solves

Here's an uncomfortable truth about email: the 'From' address you see is essentially self-reported. When you receive an email from [email protected], there's nothing inherent in the email protocol that proves it actually came from Big Company's servers. The sender just... claims it did.

This is like if anyone could write any return address on a physical letter. You could send a letter claiming to be from the White House, and the postal service would deliver it without question. That's exactly how email worked for decades, and it's why phishing became such a massive problem.

SPF changes this by letting domain owners publish a list of authorized senders. When an email arrives claiming to be from your domain, the receiving server can check: 'Did this actually come from a server that's allowed to send for this domain?' If not, the email gets flagged or rejected.

How it actually works

Let's trace what happens when you send an email from your company domain, assuming SPF is set up correctly.

You compose an email in Gmail or your email client and hit send. Your email travels to your company's mail server (or your email provider's server), which connects to the recipient's mail server. At this point, the recipient's server sees two things: the IP address of the server that's trying to deliver the email, and the domain in the 'From' address.

The recipient's server then performs a DNS lookup for your domain's SPF record. This record contains a list of IP addresses and domains that are authorized to send email on your behalf. If the connecting server's IP matches something in that list, the email passes SPF. If not, it fails.

The whole check takes milliseconds. The sender doesn't even know it happened. But that simple lookup is the difference between your email landing in the inbox and being flagged as potential fraud.

Reading an SPF record

SPF records live in your DNS as TXT records. Here's a real-world example:

This looks cryptic, but it's actually straightforward once you know the syntax. Let's break it down piece by piece.

The 'v=spf1' at the start declares this as an SPF record (version 1—there's only ever been one version). Everything after that is a list of who's allowed to send.

'include:_spf.google.com' means 'look up Google's SPF record and trust whatever servers they list.' This is how you authorize Google Workspace to send email for your domain without having to list every single Google IP address (which would be hundreds).

'include:amazonses.com' does the same for Amazon SES. If you're using SES for transactional emails, this authorizes their servers.

'ip4:203.0.113.42' directly authorizes a specific IP address. Maybe this is your own mail server, or a legacy system that sends reports.

The '-all' at the end is crucial. It means 'reject anything that doesn't match the rules above.' This is called a 'hard fail.' You might also see '~all' (soft fail, which marks failures as suspicious but doesn't reject them) or '?all' (neutral, which essentially means 'I don't know, do whatever you want'). For real security, you want '-all'.

The 10-lookup limit

Here's where SPF gets tricky, and where a lot of companies run into problems.

Every 'include' statement triggers a DNS lookup. And SPF has a hard limit of 10 DNS lookups per check. Exceed this, and your SPF record is invalid—which means all your emails fail SPF, even from legitimate servers.

This limit exists because SPF checks happen in real-time during email delivery. If a malicious actor could create an SPF record that triggered hundreds of DNS lookups, they could use it as a denial-of-service attack against DNS infrastructure. The 10-lookup limit prevents this.

The problem is that modern companies use a lot of services that send email: Google Workspace, a marketing platform, a transactional email service, a customer support tool, maybe an HR system. Each one needs an 'include' statement, and each 'include' might itself contain more 'includes.' Google's SPF record alone can use up 3-4 lookups.

If you're hitting the limit, you have a few options. You can use SPF flattening services that resolve all the includes into direct IP addresses (though this requires maintenance as IPs change). You can consolidate your email sending through fewer providers. Or you can use subdomains—marketing.yourcompany.com for marketing emails, support.yourcompany.com for support—each with its own SPF record.

SPF's limitations

SPF is essential, but it's not a complete solution. Understanding its limitations helps you build a proper email authentication strategy.

First, SPF checks the 'envelope from' address (the technical return address), not the 'header from' address (what recipients see). An attacker can pass SPF while still displaying a spoofed address to the recipient. This is why DMARC exists—it ties SPF and DKIM results to the visible 'From' address.

Second, SPF breaks when emails are forwarded. If someone forwards your email to another address, the forwarding server's IP won't be in your SPF record, so the forwarded email fails SPF. This is a fundamental limitation of the protocol, and it's why DKIM (which signs the email content) is important as a complement.

Third, SPF only tells receiving servers what to do with failures if you use '-all'. Many domains use '~all' or '?all' because they're afraid of blocking legitimate email. But this means attackers can still send spoofed emails—they'll just be marked as suspicious rather than rejected.

Getting SPF right

Setting up SPF isn't hard, but getting it right requires some thought. Here's the approach that works.

Start by auditing every service that sends email from your domain. This is usually more than you think. Your email provider, obviously. But also your marketing automation tool, your transactional email service, your CRM, your support desk, your invoicing system, maybe even your printer (some send scan-to-email). Make a complete list.

For each service, find their SPF include statement. This is usually in their documentation under 'email authentication' or 'DNS setup.' Add each one to your SPF record.

Start with '~all' (soft fail) rather than '-all' (hard fail). This lets you monitor for problems without blocking legitimate email. Watch your DMARC reports (you are collecting DMARC reports, right?) for SPF failures. If you see legitimate services failing, add them to your record.

Once you've gone a few weeks without unexpected failures, switch to '-all'. This is when SPF actually starts protecting you. Until then, it's just advisory.

Finally, set a calendar reminder to review your SPF record quarterly. Services change, you add new tools, IPs rotate. An outdated SPF record is almost as bad as no SPF record.

Frequently asked questions

My SPF record is correct but emails still go to spam. Why?

SPF is just one factor in deliverability. Spam filters also consider your domain reputation, IP reputation, email content, engagement rates, and whether you have DKIM and DMARC set up. SPF passing doesn't guarantee inbox placement—it just means you've cleared one hurdle.

Can I have multiple SPF records for one domain?

No, and this is a common mistake. If you have multiple TXT records that start with 'v=spf1', SPF checks will fail. You need exactly one SPF record that includes all your authorized senders.

What happens if I exceed the 10-lookup limit?

Your SPF record becomes invalid, and all SPF checks return 'permerror.' Most receiving servers treat this as an SPF failure, which can hurt your deliverability. Use an SPF checker tool to count your lookups before publishing changes.

Should I use -all or ~all?

Use ~all while you're setting up and testing. Once you're confident your SPF record includes all legitimate senders, switch to -all. The soft fail (~all) doesn't actually protect you from spoofing—it just flags suspicious emails without rejecting them.

e_

Written by the emailr team

Building email infrastructure for developers

Ready to start sending?

Get your API key and send your first email in under 5 minutes. No credit card required.