Sender Policy Framework (SPF) Syntax

 

Why SPF Syntax Matters

Sender Policy Framework (SPF) records are the foundation of DMARC protections and mitigate a great deal of email spoofing and impersonation just on their own. SPF records delineate which mail servers (or services) are allowed to send mail on behalf of a domain, which include both the organization’s mail server, as well as any marketing or notification services like Constant Contact, MailChimp, SendGrid and others.

These SPF records are created by adding TXT records to a domain’s Domain Name Server (DNS) and must follow a specific syntax to ensure that email servers can correctly enforce policies for authenticating emails sent from a domain.

Understanding SPF syntax allows domain owners and email administrators to create effective SPF records. Valid SPF records are essential for properly authorizing email sources and protecting an organization’s domain reputation, as even one missing character, trailing space or incorrect symbol can completely invalidate an SPF record and leave the organization vulnerable to spoofing.

 

Key Components of SPF Syntax

A sample SPF record example is below. This would be the entry made as a TXT record and consists of a few separate components.

v=spf1 [qualifier]mechanism [qualifier]mechanism [modifier]

The v=spf1 tells the receiving mail server, which is then running the SPF lookup to determine the validity of the sender, that the record contains an SPF record. It’s essentially a greeting identifying who this record is and that it will contain the desired information. The subsequent data in the SPF record is considered the “payload,” which then instructs the receiving mail server with the sending domain’s policies on who is authorized to send on behalf of that domain, followed by what to do with messages from it.

SPF syntax is defined using the following variables, which will be discussed in depth in the following sections.

  • Mechanisms: Mechanisms define the rules for which hosts are permitted to send mail (Authorize an IP address, Authorize a Domain Name, etc)

    • Ex. ip4, ip6, include, all, etc

  • Qualifiers: Qualifiers specify how to handle messages based on how they match mechanisms (Authorize and Pass, Fail and Pass, Fail and Deny).

    • Ex. +, -, ~, ?

  • Modifiers: Modifiers provide additional information or alter the behavior of the SPF record (Specialist changes for SPF records; rarely used).

    • Ex. redirect, exp

 

SPF Mechanisms

Mechanisms are the operators of the SPF world, containing the core information of an SPF record and defining who is allowed to do what on the organization’s domain. Any time that a receiving mail server receives a message, it performs an SPF lookup, which is a bit like calling the sending mail organization’s receptionist to confirm that they were the ones who sent out that message.

There are several different Mechanisms that can be used, all with different purposes:

ALL

  • The ‘all’ Mechanism is arguably the most important of them all, since it matches all IP addresses and Fully Qualified Domain Names (FQDNs) that aren’t formally specified on the SPF record. This, combined with its Qualifier (discussed in-depth in the next section), determines the fate of all messages purporting to be from the sending domain. It is typically used at the end of an SPF record, specifying how to handle IPs/FQDNs not matched by other mechanisms. 

  • Example: `v=spf1 ip4:172.28.2.0/24 ~all`

  • This SPF record authorizes emails sent from IP addresses in the range 172.28.2.0 to 172.28.2.255, while treating other sources as suspicious but not outright rejected. 

A

The “a” Mechanism is used to match against a Fully Qualified Domain Name, essentially a hostname record, of a sending mail server or other locally hosted mail service. When sending mail from a particular mail server that is on-premises, this is the recommended approach. The A record used must resolve to the sending mail server’s IP address (this includes AAAA records for IPv6-addressed mail servers).

Example: `v=spf1 a:MailServerNameHere.com ~all`

This SPF record authorizes emails sent from the IP addresses that are resolved from the A records of example.com, while treating all other sources as suspicious but not outright rejected. 

Adding a /## for CIDR notation (such as the /24 in the below example) allows for authorizing a range of IP addresses, in case there are multiple IP addresses for mail servers on the same range, some of which send and some of which receive only. This is usually only a situation that very high inbound/outbound volume organizations with on-premises mail servers will need to use.

Example: `v=spf1 a/24 MailServerNameHere.com/24 ~all`

This SPF record authorizes emails sent from the IP addresses listed in the A records of example.com and all IPs within a CIDR /24 range (254 IP addresses) around whichever IP range the A record resolves to, while treating all other sources as suspicious but not outright rejected. 

MX

The “mx” Mechanism is used to authorize one or more mail servers by the sending domain’s Mail eXchange (MX) record. Since every domain will have MX records to receive email, and usually those same ones are used to send them out as well, this can be a straightforward method of adding in a mail server or two to the SPF record. IP address ranges are also supported with this method by using different syntax, but are almost never needed.

The “mx” mechanism matches if the sender’s IP is one of the MX records for the specified domain. All the A records used for MX records are evaluated in order of priority. 

Example: `v=spf1 mx:MailServerNameHere.Domain.com -all`

This SPF record authorizes emails sent from the IP addresses associated with the MX records of MailServerNameHere.Domain.com, while explicitly rejecting emails from all other sources. 

Adding a /## for CIDR notation (such as the /24 in the below example) allows for authorizing a range of IP addresses, in case there are multiple MX servers on the same range, some of which send and some of which receive only. This is usually only a situation that very high inbound/outbound volume organizations with on-premises mail servers will need to use.

Example: `v=spf1 mx/24 MailServerNameHere.Domain.com/24 -all`

This SPF record authorizes emails sent from the IP addresses associated with the MX records of MailServerNameHere.Domain.com and all IPs within a CIDR /24 range (254 IP addresses) that those MX records resolve to, while explicitly rejecting emails from all other sources. 

IP4

The “ip4” Mechanism is used to authorize one or more mail servers by IP address, strictly limiting it to the IPv4 address space. It can be used in conjunction with other Mechanisms to add support for IPv6 addresses as well (or other address types).

Example: `v=spf1 ip4:113.79.113.15 -all`

This SPF record authorizes emails sent from 113.79.113.15, while explicitly rejecting emails from all other sources.

Adding a /## for CIDR notation (such as the /24 in the below example) allows for authorizing a range of IP addresses, but is not necessary. This is usually only a situation that very high inbound/outbound volume organizations with on-premises mail servers will need to use.

Example: `v=spf1 ip4:113.79.113.0/24 -all`

This SPF record authorizes emails sent from IP addresses in the range 133.79.113.0 to 133.79.113.255, while explicitly rejecting emails from all other sources. 

IP6

The “ip6” Mechanism is used to authorize one or more mail servers by IP address, strictly limiting it to the IPv6 address space. It can be used in conjunction with other Mechanisms to add support for IPv4 addresses as well (or other address types).

Example: ‘v=spf1 ip6:2001:0000:130f:0000:0000:09C0:876a:130b -all’

This SPF record authorizes emails sent from a singular IPv6 address, while explicitly rejecting emails from all other sources. 

Adding a /## for CIDR notation (such as the /32 in the below example) allows for authorizing a range of IP addresses, but is not necessary. This is usually only a situation that very high inbound/outbound volume organizations with on-premises mail servers will need to use.

Example: ‘v=spf1 ip6:2001:db8::/32 -all’

This SPF record authorizes emails sent from IPv6 addresses within the range 2001:db8::/32, while explicitly rejecting emails from all other sources. 

Note: If no CIDR prefix is added, a /128 for a singular host is assumed by the IP6 Mechanism.

PTR

The “ptr” Mechanism attempts to validate the sending IP address by performing a reverse DNS lookup, then validating if their A record matches the original sender’s IP. 

The PTR mechanism matches if:

  •  At least one A record for a PTR hostname matches the sender’s IP address AND

  • A valid hostname ends with the specified domain 

Note: PTR is generally discouraged as it can be inefficient and cause excessive DNS queries. 

Example: `v=spf1 ptr:MailServerNameHere.com -all`

Any server with a Reverse DNS record whose hostname ends in MailServerNameHere.com is authorized to send email for this domain, while all other sources are not allowed.

EXISTS

The “Exists” mechanism performs a DNS A record lookup and matches if any record is returned. If a valid A record is located, the match is successful. This is a relatively vague and low-protection form of SPF record and is not recommended for use.

Example: `v=spf1 exists:%{i}.%{s1}.example.com ~all`

The email is allowed if a specific DNS record exists based on the sender’s details. All other sources are treated as a soft fail.

INCLUDE

The “Include” mechanism allows owners to reference another domain’s SPF record within their own. This enables domains to incorporate other authorized senders in their policy (such as marketing agencies, mailing services like SendGrid or Constant Contact, or public relations firms). Most importantly, this is used extremely commonly today due to the widespread adoption of mail provider ecosystems like Microsoft’s Office 365 (O365) or Google’s Workspace (GW) platforms.

Since those mail providers host thousands of mail servers and it would be overly burdensome to have each of their clients add in so many entries, they maintain their own specially flattened SPF records that a client can “include” in their own SPF records to authorize O365 or GW as valid senders of the client organization’s email.

Example: `v=spf1 include:_spf.google.com include:mailchimp.com -all`

The SPF record authorizes senders specified in Google and Mailchimp’s SPF records, while all other sources are not allowed.

 

SPF Qualifiers

In SPF syntax, Mechanisms are prefixed by Qualifiers, which specify how to handle messages based on how they match Mechanisms. Qualifiers instruct the receiving mail server on how to consider the authentication status of a message when there is a match with a Mechanism’s value.

Mechanisms are checked in the order they occur in the SPF record. If a Mechanism doesn’t have a Qualifier and there’s a match, the default action is to pass authentication. When there's no Mechanism match, the action default is neutral: the message doesn't pass or fail authentication.

For example, Tangent.com’s SPF record is below:

v=spf1 include:e7g7ad1cpj.spf.director.tangent.com include:spf.protection.outlook.com -all

This SPF record authorizes only the Fully Qualified Domain Names of Tangent’s DMARC Director service (we drink our own champagne, as it were) and Microsoft’s Office 365 to send emails for the domain. The Qualifiers that precede each Mechanism instruct receiving mail servers with how to treat with messages sent from the Tangent.com domain.

Breaking down our example SPF record in manageable chunks yields these entries:

  1. The v=spf1 Mechanism tells any receiving mail server that this record is the domain’s SPF record. Only one should exist for the entire domain; if multiple exist, all SPF entries will fail.

  2. The Include Mechanism specifies mail servers or mail services that are authorized to send emails on behalf of the Tangent.com domain.

  3. The -all Qualifier is the critical factor, saying that anyone who isn’t explicitly Included (from the previous entries) is absolutely excluded and mail from them should be discarded. The “all” Mechanism exists at the end of every SPF record; it’s the symbol in front of it (the Qualifier) that is what gives it true value.


There are four main types of qualifiers for the “All” Mechanism:

  1. A ‘Plus Sign (+)’ Qualifier instructs that any sender is a valid sender and that the recipient mail server should treat messages from this FQDN with a “Pass” command from the sending domain. This is the default action when the mechanism doesn’t use a Qualifier. This is an extraordinarily dangerous and unwise Qualifier to use since it is effectively saying that anyone can spoof the organization’s domain and be authorized to do so.

  2. A ‘Tilde Sign (~)’ Qualifier specifies that the FQDN sending the messages is not authorized, but that the emails should be accepted with a warning to the end recipient or otherwise marked as being suspicious and not to be fully trusted. This is also known as a “Soft Fail” since while it technically reflects mail that failed SPF validation, the sending domain is also saying that it might be okay. As one might imagine, this is not a good way to have SPF records configured since it leaves open so much doubt and uncertainty, which attackers will absolutely exploit. This was a historical method of configuring SPF, used when testing or troubleshooting SPF setup during original deployment before switching over to the Hard Fail method. It has largely been deprecated with the advent of DMARC having taken over this role and in a far more informative way.

  3. A ‘Hyphen Sign (-)’ Qualifier states that any server that isn’t part of that Include list that is sending the message is not authorized and that the message should be discarded with prejudice, known colloquially as the “Hard Fail.” This is the sign of a formally defined and well-configured SPF record wherein the sending domain has made a hard statement about who is allowed to send and who isn’t.

  4. Lastly, the ‘Question Mark (?)’ Qualifier is a sign of neutrality in the authentication decision, wherein the sending domain does not specify what should be done with the message either way. The entire decision is left to the receiving server and this is functionally similar to not having an SPF record. The Question Mark Qualifier is another vestigial Qualifier from the early days of SPF and bears no value today.

 

SPF Modifiers

SPF Modifiers are optional components that provide additional functionality without directly affecting how messages are authenticated. They are name or value pairs separated by an “=” sign. Modifiers appear at the end of an SPF record. 

Note: Modifiers can only appear once in a record. Unrecognized modifiers are ignored. 

There are two commonly used modifiers: Redirect and Exp.

REDIRECT

The “Redirect” Modifier points to another domain’s SPF record for processing. This is best used when needing to apply the same SPF content across multiple domains. If the Redirect Modifier is in play, do not use the “all” Mechanism or the Redirect Modifier will be ignored.

This primarily gets used for organizations that maintain multiple domains that are all housed within the same mail-sending infrastructure, allowing for a single unified SPF record hosted on one domain to be more efficiently used for multiple domains without having to create individual SPF records for each domain.

Example: ‘v=spf1 redirect=DomainNameHere.com’

This SPF record directs email receivers to use DomainNamehere.com’s SPF policy instead, allowing multiple domains to share the same email sending rules.

EXP

The “Exp” Modifier provides an explanation when a FAIL qualifier is present on a matched Mechanism (basically, when a message failed SPF authentication on the receiving server because the sending domain didn’t match against it). This Explainer is hosted on a TXT record on the sending domain that details a little about why the message failed SPF authentication and can be useful for the receiving mail server administrator to get a bead on why they’re not able to receive certain messages from that domain.

In practical use, EXP is not used anymore since SPF failure is fairly self-explanatory as to why the message did not make the score for authentication, but can be a nice thing to have for helping other mail server recipients troubleshoot or better understand why they’re not receiving certain messages in their mail delivery logs.

Example: ‘v=spf1 ip4:10.0.0.0/24 exp=SPFExplainer.DomainNameHere.com -all”

This SPF record authorizes sending from the IP range 10.0.0.0/24. It provides a custom explanation message stored on a TXT record at SPFExplainer.DomainNameHere.com for recipients when emails fail SPF authentication. That TXT record may point to straightforward information like “Mail for DomainNameHere.com may only be sent by servers authorized by CompanyA.com.”

 

SPF Record Evaluation Results

Below is a matrix showing possible outcomes when an email is evaluated against a domain’s SPF record. 

In almost every case, sans the intentional rejection of non-permitted senders, domain owners will want their email to be accepted by the recipient, but depending on where they may be in their DMARC journey, there may be a preference in using transitional Mechanisms to ensure that their mail is not being rejected unduly.

Generally, a professional DMARC deployment will focus on identifying and monitoring all mail sources before enforcing a “HardFail” SPF policy, but for organizations trying to get SPF set up themselves for the first time and who are a little wary about doing it incorrectly, especially given the danger of using incorrect syntax, using a “SoftFail” method can be helpful.

Intended Action Explanation Result
Accept The SPF record has authorized the sending host, such as having that host listed properly in the record. Pass
Reject The SPF record has explicitly prohibited the sending host, such as by using the -all Mechanism, declining anyone but the authorized hosts. Fail
Accept but mark The sender is not authorized, but the domain is in a transitional state of enforcing SPF/DMARC and using an ~all Mechanism. SoftFail
Accept The SPF record neither explicitly approved or denies sending host; no judgment is made on validity. Occurs with the ?all Mechanism. Neutral
Accept No SPF record exists, record contains critical formatting errors or evaluation yields no result. Neutral
 

SPF Syntax Limitations and Best Practices

Before we dive into the “big picture” realm of best practices, let’s cover the hard and fast limitations of SPF syntax. This is time to create your example SPF syntax and then run down the list to see if any of these limits are matched.

Note: Want a wizard that does this automatically? Scroll to the bottom of this page and our Analyzer will SPF validity for you.

  1. SPF records cannot be longer than 255 characters.

  2. SPF records cannot have more than 10 DNS-based lookups, such as MX or Include Mechanisms that point towards fully qualified domain names.

  3. IPv4 and IPv6 lookups can exceed 10 lookups, so long as the total number of 10 DNS-based lookups are not also exceeded.

  4. A domain cannot have multiple SPF records. Multiple SPF records for a domain will invalidate all of them and the domain gets treated as if it does not have any SPF record; a tremendous no-no.

  5. An SPF record cannot contain any uppercase characters.

  6. SPF records cannot have more than 10 PTR queries.

To ensure a domain’s SPF syntax works as intended, the following best practices are strongly recommended:

  • Avoid the `+all` Mechanism: This mechanism allows any IP address to send emails on behalf of a domain. This negates the purpose of SPF, leading to security vulnerabilities. 

  • Start with a Soft Fail: Consider starting with `~all` initially to monitor and fine tune your SPF policy. This allows domain owners to test syntax without immediately rejecting potentially legitimate emails. 

  • Avoid Overcrowding: Keep SPF records simple and limit the number of DNS lookups to under 10. Tools like DMARC Director’s SPF Record Flattening service can condense multiple SPF mechanisms into a single flattened record. Remove any SPF Mechanisms resolving to the same domain. Remove any ‘ip4’ and ‘ip6’ SPF Mechanisms not in use and see whether any address ranges can be merged.

  • Avoid the `PTR` Mechanism: This mechanism is discouraged as it involves lengthy reverse DNS lookups and places a heavier load on DNS servers. This may lead to caching limitations and SPF validation failures. 

  • Regularly Review and Update: Periodically check SPF records to ensure accuracy. This is particularly true for keeping up with Marketing Departments, since they may launch new email initiatives which won’t get any traction without them being properly qualified in the domain’s SPF record.


Have an SPF record you want to check to make sure it meets all the syntax rules above and is working fine, without all the headache of carefully checking each character? We got you. Run it through our Analyzer and let us do the heavy lifting.

There can be a lot of potential pitfalls when it comes to deploying SPF for the first time (let alone DMARC); if there is a feeling of uncertainty about it, get in contact with Tangent today and let us take you through it instead.

Previous
Previous

DKIM Tags: Everything you wanted to know

Next
Next

A Primer on DMARC Reporting: RUF and RUA