: Blog

Office365 and mailhop - SPF - a small problem.

If you use Office 365 / mailservers and also use mailhop mailservers for sending emails, you may find some of them are being quarantined or rejected
- and you may be wondering what the cause could be.

For Office365 / mailhop, the direct cause could be as simple as having the following two items in the SPF record for your domain:

In this article I show you how to save 2 DNS lookups - fixing the SPF, and also saving 31 characters PER DNS lookup.
Sometimes it IS the little things that matter

You can use the DNS record examples in this article to test the solution.
These are not for production use, as this is a server I test things with is rebooted regularly and may be offline.

To reiterate:

If you need to implement the solution specified in this article,
YOU MUST publish your own copies of the DNS records using a more resilient platform.

If you point to my DNS then this could lead to loss of emails as DNS lookups may fail without warning.
No warranty, neither expressed, nor implied. Errors & Omissions Exempted:.

Before we continue:
Many thanks to Scott Kitterman for his SPF Record Testing Tools
These are a valuable resource for learning about and testing
SPF compliance.

The Problem and solution:

I have already advised mailhop and mailchannels of this, but at time of writing the SPF record still requires 9 DNS lookups to process, and contained with it is which requires 3 of those DNS lookups on it's own.
If your email delivery is more important and can not wait until they implement a solution, there is one below, read on:

If at this point you are wondering how this SPF record could be a problem here's why:

When processing an SPF record for an inbound email, SPF has a lookup limit of 10 DNS lookups MAXIMUM.
(Opens in a new tab, http only at time of writing).

For the explanation, here is an example using the simplest SPF record for this combination of email providers:
v=spf1 -all

In theory, this SPF record states:
"allow the servers specified by and the servers specified by to send my emails"
-all states:
"Do not allow other servers to deliver my emails".

Looks good doesn't it?
- I'm afraid it isn't - at least not yet
There is a fix, but first to explain the problem:

If you only sent emails via mailhop, and had an SPF record like this:
v=spf1 -all
Then you have NO problem - only 9 DNS lookups are required to process the SPF - all is good with the world.

BUT if you send via / Office365 servers as well as mailhop then:
requires 3 DNS lookups to process,
requires 9 DNS lookups to process...

- and 12 DNS lookups in total does not comply with the specification for SPF.

The reason for the 10 DNS lookup limit in the specification for SPF is to reduce the risk of DoS attacks.
That being the case the logical thing is to try and see if this issue can be resolved.

At time of writing (6th October 2018 @ 14:57 BST) this problem with combining the SPF for:
can be resolved quickly and fairly simply.

Here is the (numbered) chain of DNS lookups required in sequence to process the SPF record:





See the red ones? Those are the ones that are outside of the specification for SPF.

This completely breaks the SPF record.

If you are wondering why - a perfectly formatted SPF record - is in bold, here's why: contains:
v=spf1 ~all
1 DNS lookup is required for
1 DNS lookup is required for

If we can remove these 2 DNS lookups we can solve this problem and fix the SPF record. contains this:
v=spf1 ip4: ip4: ip4: ip4: ~all
(total 92 characters - Why is this important? - read on) contains this:
v=spf1 ip4: ip4: ip4: ip4: ip4: ip4: ip4: ~all
(total 161 characters)

Why the number of characters is important:
There is a limit of 255 characters within a DNS TXT record.*
161+92 = 253 characters. It will easily fit in one TXT record .

* yes, well, sort of. More information later in this article.

If we combine the two TXT records together (and re-order the IP addresses in ascending order to aid manageability) we end up with this:
v=spf1 ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ~all
(total 220 characters)
Saving 11 characters by de-duplicating v=spf1 and v=spf1,
and 20 characters by removing /32 - as it is not required by the specification for SPF.

If we publish this as a DNS record somewhere else:

then publish a version of the SPF record that replaced with

Then we end up with this SPF record:
v=spf1 -all

Which I published as:

Then we end up with this chain of DNS lookups:





And when you test the SPF record:
v=spf1 -all
at Kitterman's SPF Query Tool you get this:
evaluating... <a href=SPF record passed validation test with pySPF (Python SPF library)!">

i.e. Problem Solved.

So this is what we have achieved:
1 - we've cured the issues of compliance with the specification for SPF, making an SPF record that functions correctly, exactly as desired
2 - we've reduced the number of DNS lookups required, saving DNS lookups, which saves time, bandwidth, processing cost
3 - we've reduced the number of characters returned by three of the TXT records by combining them into one, saving time, bandwidth, processing cost
4 - we've increased the manageability of the original SPF record, by completely putting the ip4: addresses in ascending order
5 - we've further reduced the size of the SPF record by removing /32 from the end of ip4: addresses. (SPF specification DOES NOT REQUIRE IT!)

There are some caveats of course, you have to monitor all the SPF records for changes, especially

If you want assistance with this type of issue, contact for a quote.

Right, now there are some additional points I skimmed on earlier, here is a bit more about them.

DNS TXT record limit of 255 chars:
Well, you can have longer ones - multiple records each of no more than 255 chars enclosed within speechmarks - but this can have it's own related set of problems.

Last Updated 2019/06/19 00:11 CET.

Cookie Policy
Privacy Policy
Security Policy
Terms & Conditions © 2019 Allan Wallace