Article URL: https://dmarcguard.io/blog/spf-record-syntax/ Comments URL: https://news.ycombinator.com/item?id=49155626 Points: 22 # Comments: 5

SPF record syntax follows one shape: a single DNS TXT record that starts with v=spf1, followed by space-separated terms — mechanisms with optional qualifiers, then modifiers — evaluated left to right until the first match. Here is a complete record: That one line authorizes a /24 network and a third party’s servers, then fails everything else. Every rule governing it lives in RFC 7208, the SPF standard published in April 2014. This page is the full reference: every mechanism, every qualifier, both modifiers, the complete macro table, evaluation order, DNS lookup limits, and record placement rules — each with the RFC 7208 section that defines it. If you want protocol fundamentals first — why SPF exists and how it fits with DKIM and DMARC — start with our SPF guide. If you build and maintain records, bookmark this. An SPF record is one string of text in the RDATA of a single TXT record, and its grammar has exactly three kinds of parts: a version tag, mechanisms (each with an optional qualifier), and modifiers. The version tag must be exactly v=spf1 — a record starting v=spf10 is discarded, not partially matched (§4.5). Terms are separated by spaces. Mechanism names are case-insensitive, and terms containing none of =, :, or / are mechanisms (§4.6.1). One syntax error anywhere invalidates the whole record: check_host() — the receiver’s evaluation routine, as the RFC names it — validates SPF syntax first and returns PermError immediately if anything is malformed, without evaluating a single term (§4.6). That is why one stray character can fail authentication for every message a domain sends. Eight mechanisms exist, and each either matches the connecting IP or does not. RFC 7208 §5 splits them into basic framework mechanisms (all, include) and designated-sender mechanisms (a, mx, ptr, ip4, ip6, exists). Before the full table: most real-world records use only include, ip4, ip6, and all — the rest of this reference exists so you can read other people’s records, not because your own needs them. You can parse any published record term-by-term — with each mechanism’s cost and RFC cite attached — using the SPF syntax inspector. all always matches, which is why it belongs at the end as the explicit default (§5.1). Everything after it is dead text: “Mechanisms listed after all MUST be ignored,” and any redirect= modifier is ignored whenever all appears anywhere in the record (§5.1). A record without a trailing all or redirect= silently defaults to Neutral (§4.7).