Hooking up additional spam filters in front of or behind Office 365

 Note: This blog post reflects my own recommendations.

Over here in Exchange Online Protection (EOP), people sometimes ask me why we don't recommend hooking up multiple layers of filtering in front of solution. That is, instead of doing one of these:

Internet -> EOP -> hosted mailbox
Internet -> EOP -> on-prem mail server

... a customer wants to do something like this:

Internet -> on-prem mail server -> EOP hosted mailbox
Internet -> on-prem mail server -> EOP -> on-prem mail server

... or even this:

Internet -> another cloud filtering solution -> EOP hosted mailbox
Internet -> another cloud filtering solution -> EOP -> on-prem mail server


If you read through our Office 365 Mailflow Best Practices, you'll see that those ones are listed as not being supported. If you want to put another filter in front of EOP, you should ensure that that other filtering solution is doing your spam filtering. If your on-prem mail server does not have spam filtering, you should install one. In other words, I do not recommend pipelining and double spam filtering your email.

So why do I recommend this?

After all, adding more malware filters gives you better protection. So shouldn't this result in better spam protection?


EOP makes use of a lot of sending IP reputation. So, suppose the sending IP is In the supported case, it looks like this:

Internet, -> EOP.

In the unsupported case, it looks like this:

Internet, -> on-prem mail server -> EOP


In the first case, EOP sees the original IP. In the second case, it sees the on-prem mail server's IP. Since the on-prem mail server will never be on an IP reputation list, the email must be spam-filtered instead and not blocked at the network edge. This loss of original IP degrades the overall experience.

But why can't we simply crawl through the headers of a message, looking for the original IP? After all, some solutions do that.

There are numerous reasons why we don't do this but here's the biggest one - our IP throttling doesn't work.

EOP's IP throttling is a variant of graylisting. If email comes from a new IP address [1], EOP throttles that IP by issuing a 450 error, instructing the sending mail server to go away and try again later. Most legitimate mail servers retry, whereas most spammers give up and move on to the next message. This is a technique that has been used in spam filtering for years, and when EOP introduced it, we saw a lot of spam from new IPs get blocked (that is, get blocked and not retry)..

But if you do something like this:

Internet, -> on-prem mail server -> EOP

Even if EOP crawled through the headers and extracted the original IP address, and then issued 450's to the connecting mail server, we'd be issuing the 450's to the on-prem mail server ( and not the original spammer. This would then force queues to build up on the on-prem mail server and then everything starts breaking. Either the on-prem mail server falls over because it can't handle the queues building up, or it retries and tries to shove the message through EOP anyhow. We may not yet have enough reputation to make a spam verdict downstream. IP throttling works very well in the service.

But EOP assumes that in order to give you the best experience, we're using all of the tricks up our sleeve to stop spam - including IP throttling. But putting another filter in front of EOP removes a key piece of that filtering. It isn't made up elsewhere downstream.


IP throttling is a key piece but the reality is that any throttling, sending IP based or not, that issues 450 responses and assumes that good senders retry and spammers do not, won't work properly by sticking something in-between the origin and EOP.

And since all of our filtering is not being applied - even if we crawled through headers - we would not get the same filtering experience because of the behavior differences between spammers (who won't retry) and the mail server (who will). We wouldn't apply throttling at all if we could get the same experience elsewhere.

That's why double spam-filtering is not supported, and why we don't go out of our way to make it work.


That's not to say you can't put another service in front of EOP. But if you do:

  • IP reputation blocks, and IP throttling, do not work properly
  • DNS checks that use the sending IP do not work properly, such as PTR lookups, SPF checks, DMARC checks, and even DKIM if you route it through a mail server that modifies the message content
  • IP Allow entries do not work properly because the original sending IP has been lost
  • Some rules in the spam filter will not work properly because they look for a particular IP range or sending PTR
  • The Bulk mail filter does not work properly
  • The antispoofing checks do not work properly


All of this will result in more spam getting delivered, and more good email being misclassified as junk.

On the other hand, here's what does still work:

  • Malware filtering
  • Exchange Transport Rules (ETRs) that don't rely upon the sending IP
  • Safe and blocked senders
  • Safe and blocked domains
  • Advanced Threat Protection (Safe Links and Safe Attachments)
  • Some parts of the spam filter that only look at content still work, e.g., malicious URLs

So, filtering will work but it won't be as good.


If you are going to use a third-party to do spam filtering, we recommend you do it this way: Using a third-party cloud service with Office 365. That points your organization's MX record at EOP so that we are in front and the third-party is behind us. Many add-on services recommend you do it this way because they assume you have a spam filter in front of their service. In many cases, you can probably find an equivalent service from Office 365 to use, in place of what you were using that other appliance or cloud-filtering service for so you don't need to run multiple services or appliances.

If you have to put a third-party in front of EOP such that your MX doesn't point to EOP, then we recommend that you rely upon this third party to do spam filtering by having it stamp a set of x-headers for spam and non-spam, and then writing ETRs to look for those headers to mark as spam (SCL 5-9) and take the spam action, or non-spam (SCL -1, not 0-4) so it gets delivered to your inbox. It still goes through Malware, ETRs, Safe and blocked senders, and Advanced Threat Protection. Our other services (e.g., Data Leakage Protection, Advanced Security Management) still do, too.

Or, if you send your email to an on-prem mail server and then back into Office 365, you should set up connectors (if on-prem is Exchange) so message properties can be preserved between the service and your on-prem server:

If you have to put a third-party in front of EOP and want double spam-filtering, you will probably notice more misclassified email than if you used either of the above two options.

Hope this helps.


[1] There's much more to IP throttling than simply being from a new IP address without previous history, it's more complicated than this.


Comments (9)
  1. Alin says:

    Hello Terry,

    What do you think would be the best way of setting up a cloud service application that does not have spam detection abilities?

    Thank you,

    1. tzink says:

      Hi, Alin,

      Without knowing more about the setup I can’t really give advice on how to set up spam filtering in a cloud service that is not Office 365.

  2. turbomcp says:

    What about:
    mailboxes in hybrid(onprem and in cloud)
    Internet>>365/EOP>>third party onprem>>back to 365 ?

    thanks in advance

    1. tzink says:

      That will work so long as you have enough connectors and Exchange Transport Rules to look for headers and route mail accordingly.

  3. Skip says:

    We are initial stages of configuring a hybrid environment between onprem and Exchange online. Currently our MX records point to proofpoint. We will be using proofpoint for all email filtering for the next several months, however the goal is to move away from proofpoint. I’m fairly certain routing email from proofpoint to EOP is going to be straight forward. Create a send connector in proofpoint that relays all email for domain.com to EOP. Then in EOP add the proofpoint ip address to the default connection filter ip allow list. All outbound email from onprem and online will go through EOP. EOP will send directly to the internet. My main concern with this setup is around Microsoft’s throttling and ip reputation. If we configure forced TLS between proofpoint and EOP using a partner connector, will doing this stop or prevnt EOP throttling and reputation? There will thousands of emails per day sent from proofpoint to EOP, and I cant risk EOP throttling proofpoint because it doesn’t like the amount of email that is being sent


    MX record points to proofpoint. proofpoint filters emails for spam and malware. proofpoint’s smart host is configured to point to domain-com.mail.protection.outlook.com for all email sent to domain.com. EOP contains all proofpoint ip’s in a whitelist.

    EOPOnprem (hybrid mail flow)



  4. Do not, that what is presented here as ‘bad practice’, is mentioned as recommended practice on other locations. For example, on putting hosted hygiene solutions in front of EOP:
    “To do this for inbound mail, you should redirect your email messages to the third-party provider by changing your MX records to point to the third-party provider, and then redirect the messages to EOP for additional processing. ”

  5. We handle all of the “But if you do” items (greylisting, etc) at the upstream gateway. We would like the SPF checks to not show “fail” in Received-SPF and Authentication-Results. Is there a way to pass through the correct SPF result using a X-header or something like that?

    1. tzink says:

      No. You’d have to do all of your filtering upstream and then pass the result down to Office 365 and then use Transport Rules to set the spam or non-spam verdict on the message. Office 365 won’t interpret any previously stamped SPF result.

  6. Jon R says:

    We use a 3rd party email filter in front of our hybrid. We are in the process of updating the inbound mail route to go thru 365 instead of our on-premise. We have multiple domains on our system, 3 of which are used for email. When setting up the routing on our 3rd party system, should we set each domain to use the MX record assigned by Microsoft as the inbound route or are we ok just using our primary domain MX record from Microsoft?

Comments are closed.

Skip to main content