MailCheck

SPF record setup and check: syntax, examples, common mistakes

SPF lists the servers that may send mail for your domain. It is a single TXT record in DNS, and it is broken surprisingly often.

Updated: 05 November 2026

What SPF checks

When a mail server accepts a message, it knows the IP address of the server handing it over. With SPF (Sender Policy Framework, RFC 7208) it checks DNS to see whether that IP is allowed to send for the sender's domain. If the IP is listed, the result is pass. Otherwise it is fail, softfail or neutral, depending on the record.

One detail catches people out all the time. SPF looks at the envelope address, the MAIL FROM that later becomes the Return-Path (for bounces without one, the server's HELO name). The sender address your recipient sees in their inbox is not part of the check at all. That is why newsletter services often send with their own envelope domain and still get a green SPF result. Whether the two domains line up is for DMARC to decide.

What an SPF record looks like

The record is a TXT record on the domain itself. A company using Microsoft 365 plus its own server for scan-to-mail might publish:

example.com.  TXT  "v=spf1 ip4:203.0.113.25 include:spf.protection.outlook.com -all"

Receivers read it left to right, and the first match wins:

Part Meaning
v=spf1 version tag, must come first
ip4: / ip6: single addresses or networks, e.g. ip4:203.0.113.0/24
a / mx the domain's IPv4 and IPv6 addresses (A/AAAA) or those of its MX hosts
include: pulls in a service provider's SPF record
-all every other server: fail

Each mechanism can carry a qualifier. + is the default and means allowed, - means reject, ~ means suspicious (softfail) and ? means neutral. If you use Google Workspace, the include is include:_spf.google.com.

-all or ~all?

The end of the record tells receivers how to treat mail from servers you did not list. -all is unambiguous, while ~all only marks such mail as suspicious. During roll-out ~all makes sense, because you may not yet know whether a copier, a web shop or some old line-of-business software sends mail in your name. Once every sender is covered and DMARC is enforced, finish the record with -all.

Never use +all. It allows every server on the planet to send as your domain, which defeats the point of having a record.

The most common mistakes

Two SPF records. A domain may have exactly one TXT record starting with v=spf1. If a provider simply adds a second one, SPF is invalid for the whole domain (permerror). Merge the includes into one record.

More than 10 DNS lookups. Every include, a, mx, ptr, exists and redirect costs a lookup, and providers' includes bring their own. Go over 10 and the check stops, again with permerror. This creeps up on you: first the CRM is added, then the ticketing system, and one day a provider extends its own record. On top of that, no more than two lookups may come back empty.

Forgotten senders. Invoices from the ERP system, the contact form on the website, the scanner in the hallway. Whatever is missing from the record ends up in spam or gets rejected.

Deprecated ptr. The mechanism is slow and unreliable, and RFC 7208 says not to use it. Replace it with ip4/ip6 or an include.

Missing subdomain records. SPF is not inherited. If you send from news.example.com, that name needs its own record. Domains that never send mail should publish v=spf1 -all, so spammers lose an easy address to send from.

Where SPF reaches its limits

When a recipient forwards your message automatically, it is their server that delivers it onward. Its IP is not in your record, so SPF fails. A valid DKIM signature usually survives forwarding. That is why DMARC does not depend on SPF alone, and why you should set up both.

Checking SPF

A DNS lookup shows you the record and nothing more. To see whether it covers the mail you actually send, you need a real message. Send one to ZwoMailCheck and the result page shows which IP it came from, whether SPF passes for exactly that server, how many of the 10 lookups are used and whether the envelope domain matches your sender.