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.
A sample SPF record example is below. This would be the entry made as a TXT record and consists of a few separate components.
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 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:
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.
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.
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.
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.
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.
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.
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.
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:
There are four main types of qualifiers for the “All” Mechanism:
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.
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.
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.”
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 |
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.
To ensure a domain’s SPF syntax works as intended, the following best practices are strongly recommended:
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.