SPF Records for Cold Email: A Practical Guide
An SPF record is a DNS TXT entry that lists which servers are allowed to send email for your domain. For cold email it matters because mailbox providers check SPF before they decide where your message lands. Each domain should have exactly one SPF record, it must stay under ten DNS lookups when evaluated, and it should end in ~all or -all to tell receivers how to treat unlisted senders.
What SPF actually does
SPF (Sender Policy Framework) answers one question: is this server authorised to send mail for this domain? When a message arrives, the receiving server reads the envelope sender’s domain, looks up that domain’s SPF record in DNS, and checks whether the sending IP is on the approved list.
If the IP matches, SPF passes. If it does not, the record’s final mechanism decides what happens — soft fail or hard fail. SPF only validates the sending source. It does not check the message contents; that is DKIM’s job, and the policy for handling failures is set by DMARC.
Since February 2024, Google and Yahoo require bulk senders to pass SPF and DKIM and publish DMARC. A missing or broken SPF record is one of the fastest ways to land in spam, so it is the first thing to get right.
One SPF record per domain
A domain may have only one SPF record. This trips up senders who add a second v=spf1 TXT entry for a new service instead of editing the existing one. Two SPF records is not “extra coverage” — it is a permerror, and most receivers treat a permerror as a failure.
The fix is to merge every sending source into a single record. If you send through Microsoft 365 and one other service, both include mechanisms go in the same line:
v=spf1 include:spf.protection.outlook.com include:_spf.example-service.com -all
For a Microsoft 365 setup with no other senders, the record is usually just:
v=spf1 include:spf.protection.outlook.com -all
The 10 DNS-lookup limit
SPF caps the number of DNS lookups performed during evaluation at ten. This is a real protocol limit, not a guideline. Go over it and the record returns a permerror — the same outcome as having no valid SPF at all.
The lookups come from mechanisms that resolve other records. Each of these counts toward the ten:
| Mechanism | Counts as a lookup? | Notes |
|---|---|---|
include | Yes | Each nested include can trigger further lookups |
a | Yes | One lookup per a mechanism |
mx | Yes | One, plus lookups for the returned hosts |
ptr | Yes | Discouraged; slow and unreliable |
exists | Yes | One lookup |
ip4 / ip6 | No | Literal addresses, no DNS resolution |
all | No | The terminal mechanism |
A single include can expand into several lookups if the provider’s record itself contains includes. Stack three or four email services and you quietly exceed the limit. The practical rules: list only services that genuinely send for the domain, prefer ip4/ip6 literals where you control the addresses, and remove includes for tools you no longer use. If you cannot get under ten honestly, “flattening” the record into literal IPs is the usual escape, at the cost of needing to update it when the provider’s IPs change.
-all vs ~all: what the ending means
The mechanism at the end of an SPF record tells receivers what to do with mail from servers that are not on the list. Two endings matter for cold email:
| Ending | Name | Effect on unlisted senders |
|---|---|---|
-all | Hard fail | Receiver should reject or treat as a clear failure |
~all | Soft fail | Mark as suspicious, usually still accept |
+all | Pass all | Never use — authorises every server on the internet |
-all is the stricter and ultimately the stronger signal. It only works in your favour once you are certain every legitimate sender — your sequencer, your newsletter tool, any transactional service — is already listed. Miss one, and that mail starts hard-failing.
~all is the safer default while you are still confirming your sending sources. It lets receivers flag unlisted mail without outright rejecting it, which buys you room to discover a forgotten sender before it costs you delivery. A common path is to launch with ~all, verify nothing legitimate is failing, then tighten to -all. Never ship +all; it defeats the entire point of SPF.
SPF in a cold-email setup
Cold email usually runs on dedicated secondary sending domains rather than your primary domain, and each one needs its own correct SPF record. When you send through Microsoft 365 connected to a sequencer, the relevant include is Microsoft’s — the sequencer relays through the same authenticated mailboxes, so it does not normally add its own SPF source.
The classic failure is a domain that “has SPF” but lists the wrong source, so the record exists and still fails for your actual sending path. Verify that SPF passes for a real test send, not just that a record is present. Our SPF, DKIM, and DMARC setup checklist covers testing all three together, since SPF alone is necessary but not sufficient for staying out of spam.
How Mailionaire approaches this
When Mailionaire stands up a sending domain, SPF, DKIM, and DMARC are written and verified automatically as part of provisioning each isolated Microsoft 365 tenant — one correct SPF record per domain, no second-record mistakes, no lookup overflow. It is part of the flat $50 per active domain per month, with no separate authentication setup to manage. See how it works for the full provisioning flow.
FAQ
What should my SPF record look like for cold email?
A single TXT record at the domain root, starting with v=spf1, listing only the services that actually send for the domain, ending in ~all or -all. For Microsoft 365 that is typically v=spf1 include:spf.protection.outlook.com -all. Keep it to one record and under ten DNS lookups.
Should I use -all or ~all in my SPF record?
Use -all (hard fail) once you are confident every legitimate sender is listed; it tells receivers to reject unlisted sources. ~all (soft fail) marks unlisted mail as suspicious without rejecting it, which is safer while you are still confirming your sending sources. Both are valid; -all is stricter.
Why does my SPF record keep failing with too many lookups?
SPF allows a maximum of ten DNS lookups when it is evaluated. Each include, a, mx, ptr, and exists mechanism counts. Stacking several email services in one record blows past the limit and causes a permerror, which fails authentication. Flatten the record or remove unused includes.
Does a correct SPF record make my cold email legal?
No. SPF is a technical authentication check, not a legal permission. Whether you may send depends on the recipient's jurisdiction — Germany's UWG §7(2) generally requires prior opt-in for advertising email, including B2B. The sender remains responsible. This is not legal advice.
Mailionaire provisions real, isolated Microsoft 365 mailboxes for cold email — built in Switzerland, with optional EU/Swiss data residency — then monitors and replaces them as they wear out. One flat price per domain. See how it works →