An SPF record is a single line of space-separated terms in a TXT record at the domain itself. Once you can break one into its parts, the rest of SPF is detail.
Anatomy
v=spf1 ip4:192.0.2.0/24 include:_spf.example.net a:mail.example.com -all
v=spf1— the version. Required, and must be first. A record that does not start with this is not an SPF record and receivers ignore it.ip4:192.0.2.0/24— a mechanism. Matches if the connecting IP is in this range.include:_spf.example.net— a mechanism that evaluates another domain’s record.a:mail.example.com— a mechanism that matches the A/AAAA records of that name.-all— the terminal mechanism. Matches everything not already matched, with a fail qualifier.
Terms come in two kinds
- Mechanisms can match the connecting IP. They are evaluated strictly left to right and the first match wins, so order is meaningful.
- Modifiers —
redirect=andexp=— change evaluation rather than matching an address. Each may appear at most once, and their position in the record does not matter.
Finding the record
"v=spf1 include:pp._spf.paypal.com include:3ph1._spf.paypal.com include:3ph2._spf.paypal.com include:3ph3._spf.paypal.com include:3ph4._spf.paypal.com include:sendgrid.net include:aspmx.pardot.com ~all"
That record is worth a second look, because it shows a pattern you will want later. Instead of listing addresses directly, PayPal delegates to five sub-records of their own — four of them named 3ph, for third party. It is a deliberate structure that lets different teams manage different parts without editing a shared record.
Three rules that break records
- Exactly one SPF record per domain. Two records beginning
v=spf1is a permerror, not a merge and not a first-one-wins. RFC 7208 §4.5 requires receivers to treat it as an error, because there is no defined order for TXT records and so no basis for choosing. This is the single most common way a working record is broken: someone adds a second one for a new platform. - The record lives at the domain, not at a subdomain of it. SPF for
example.comis a TXT record atexample.com. There is no_spfprefix, and SPF is not inherited by subdomains —mail.example.comneeds its own record, or it has none. - The obsolete
SPFrecord type is not used. RFC 4408 defined a dedicated type 99; RFC 7208 §3.1 removed it. Publish TXT.
Long records are split, and the split is invisible
A TXT record is a sequence of strings of at most 255 characters each. A long SPF record is split into several, and receivers concatenate them with nothing in between. Some interfaces show the pieces, some hide them. If a record is edited by hand and a space is introduced at a join, the resulting record is subtly wrong in a way that is very hard to see.