10 Most Common Errors in SPF Records

In our analysis of the SPF records of the top 1 million websites, we uncovered over 20,000 domains with invalid SPF setups. In this blog post, we not only reveal the ten most common types of errors we encountered but also offer advice on how to avoid these issues, along with practical tips for fixing them.

1. Multiple SPF TXT Records

According to RFC 7208, the document that specifies SPF, “multiple SPF records are not permitted for the same owner name,” and an email server is supposed to produce a permerror result in cases where more than one record is found. Despite this, we identified nearly 13,000 domains among the top 1 million most-visited websites with two or more SPF records. One domain, i-scream.co.kr, even had a total of 17 SPF records. An example of a quite popular domain with two SPF records is howstuffworks.com:

$ dig TXT howstuffworks.com | grep \"v=spf1
howstuffworks.com.      0       IN      TXT     "v=spf1 include:_spf.google.com ~all"
howstuffworks.com.      0       IN      TXT     "v=spf1 include:servers.mcsv.net ?all"

Clearly, the administrators of howstuffworks.com intended to authorize Gmail (google.com) and Mailchimp (mcsv.net) to send emails on behalf of the domain. However, instead of adding two separate SPF records, they should have merged them into a single record, such as v=spf1 include:_spf.google.com include:servers.mcsv.net ~all.

2. Missing Spaces in the SPF Record

Another frequent error we encountered involves SPF records lacking space characters. For instance, the record from workcanvas.com is incorrectly formatted as v=spf1include:spf.mandrillapp.com?all, while the correct format should be v=spf1 include:spf.mandrillapp.com ?all.

This issue often arises when admins add the record to the DNS zone file without enclosing the value in double quotes. Without these quotes, the DNS server interprets the spaces as separators, resulting in the creation of multiple strings: v=spf1, include:spf.mandrillapp.com, ?all. These are then concatenated without spaces by the client querying the record, leading to an improperly formatted SPF record.

3. Spaces Where They Don’t Belong

According to the SPF specification, there shouldn’t be any whitespace between a mechanism or modifier name and its corresponding value. For example, introducing whitespace into +a:192.168.0.1/24 will render the entire SPF record invalid. Consider an SPF record like v=spf1 ip4: 148.59.154.215 ip6:2607:f0d0:1202:128::3 a:mx1.gurudns.net -all, which we found at gurudns.net. This record will always generate a permerror, due to the incorrect space character between ip4: and 148.59.154.215.

4. Unknown Mechanisms

The mechanisms in an SPF record define the rules for evaluating whether emails from specific IP addresses are authorized by the domain owner. Allowed mechanisms include a, mx, ip4, ip6, include, exists, and ptr. If an email server detects an unknown mechanism name, it is supposed to generate a permerror result.

The most common unrecognized mechanism name we encountered is ipv4, as seen in the SPF record of idrlabs.com: v=spf1 mx ipv4:172.104.21.37 ~all. This should have been ip4. Similar typos include ip (which should be ip4) and ipv6 (instead of ip6). Additionally, some records incorrectly use aaaa, even though a matches both IPv4 and IPv6 addresses.

5. SPF Record Doesn’t Start with v=spf1

An SPF record must begin with the version section specified as v=spf1 (case-insensitive), followed by a space character or the end of the record.

When analyzing the TXT records of the top one million domains, we discovered thousands of records that deviate from this rule yet appear to be intended as SPF records. Here are some illustrative examples from the dataset:

A recurring issue identified was SPF records enclosed in quotation marks ("v=spf1" instead of v=spf1) and records with leading whitespace ( v=spf1 instead of v=spf1).

6. Multiple TXT Records Merged into One

Besides an SPF record, most domains also have other TXT records, for example, to verify domain ownership for Google Search Console or Facebook. Instead of maintaining these values in separate TXT records, we observed several domains where the SPF record was incorrectly merged with these verification values. Here are two examples:

7. Illegal Characters in the SPF Record

The SPF specification mandates that terms within an SPF record must be separated by one or more space characters (ASCII code 32). The use of other separator characters is not allowed and leads to a permerror. Nonetheless, we discovered a significant number of SPF records containing illegal characters. For example, consider the SPF record of paramountplus.com:

$ dig TXT paramountplus.com | grep \"v=spf1
paramountplus.com.      0       IN      TXT     "v=spf1 include:_netblocks.viacom.com include:_spf.salesforce.com include:spf.protection.outlook.com include:servers.mcsv.net include:stspg-customer.com\010include:_spf.google.com include:_spf-customer.tbxnet.com ~all"

As the dig output illustrates, the record contains a line feed character (\010), rendering it invalid. Other illegal characters we frequently encountered include tabs (ASCII code 9) and character sequences representing Unicode characters, such as no-break spaces, zero-width spaces, and en dashes. Unicode characters can be particularly deceptive; for instance, a no-break space may appear identical to a normal space, and a zero-width space may not be visible at all on the screen. In such cases, pasting the text into a Unicode character inspector tool can be useful for identifying the presence of unwanted characters.

8. Invalid Domain Names

The mechanisms include, a, mx, ptr, and exists within an SPF record can be followed by a : and a domain name, as seen in include:spf.example.com and a:mx.example.com. However, the use of an IP address instead of a domain name is not permitted. For instance, the SPF record for librespeed.org, v=spf1 a:89.40.173.80 mx -all, is invalid due to the inclusion of an IP address following a.

Additionally, prefixing domain names with https:// or any other URI schemes renders an SPF record invalid. This mistake can be seen in the SPF record for captainbi.com: v=spf1 include:http://spf.mail.qq.com ~all.

9. Invalid IP Addresses

Similar to the issue with invalid domain names, we encountered hundreds of instances where ip4 and ip6 mechanisms were accompanied by invalid IP addresses. In some cases, the SPF record contained unresolved placeholders, as seen in v=spf1 mx ip4:[corpIP] include:mktomail.com ~all for company.com. In other instances, a domain name was mistakenly used in place of an IP address, as in v=spf1 a mx ptr ip4:app.jackrabbitmail.com include:smtp.secureserver.net include:app.jackrabbitmail.com ~all. Additionally, we observed several records with incomplete IP addresses, such as v=spf1 a mx ip4:95.128.180 ?all, where an octet is missing, or with redundant ip4:ip4: parts (v=spf1 a mx ip4:ip4:209.94.103.0/24 ip4:208.88.137.117 ip4:208.88.137.118 ~all).

10. Missing Mechanism or Modifier Names

In an SPF record, each mechanism (such as include or ip4) or modifier (such as redirect) can be associated with only one value. To specify multiple values for a similar type, such as several IPv4 addresses, they must be included as separate mechanisms (e.g., ip4:192.168.0.1 ip4:10.0.0.1).

Consequently, records like v=spf1 include:_spf.google.com mail.kubernetes.io ~all (found at kubernetes.io) and v=spf1 ptr ip4:192.254.121.104/29 50.31.32.95 192.254.120.212 -all (underarmour.fr) are invalid. Such configurations lack the necessary mechanism or modifier names for each value and, as a result, generate a permerror during evaluation.

Final Words

Correctly setting up SPF is challenging and prone to mistakes. This is evidenced by the numerous invalid SPF records we discovered among the top 1 million domains. Therefore, it’s crucial to meticulously test your email setup after implementing SPF, DKIM, and DMARC. An effective method to do this is through our free DMARC Checker.

For further insights, consider reading our articles on the most common DKIM configuration errors and the most common DMARC errors we’ve uncovered in our analysis.