Figure out which spam filter marked a message as spam

It has been quiet around these parts as of late. Much too quiet. To put that to an end, I have a handy tip today that could help in your spam troubleshooting adventures. For various reasons, organizations sometimes need to create multiple spam filters in Exchange Online. When troubleshooting a false positive (an inbound message that was marked as spam incorrectly), it can be tricky to figure out which spam filter was used to process the message. Well, that changes today with this tip.

How spam filters are evaluated

Let’s first look at how spam filters are evaluated in Exchange Online. Even when multiple spam filters have been created, every inbound message is only evaluated by a single spam filter. When a message is received, Exchange Online will first look at the spam filter that has a priority of 0. If the “applied to” criteria in that filter matches the message, then that spam filter, and only that spam filter will be applied to the message. If the “applied to” criteria in that first spam filter do not match the message, then Exchange Online will look at the next spam filter. Once a match is found, then only that spam filter will be used. If no match is found, then the Default spam filter will be used.


So you have a false positive and need to figure out which of the spam filters in EOP caused the message to be junked. Maybe the message was junked because of the sender of the message being on the block list in one of your spam filters, or maybe it was junked because of an Advanced Spam Filter (if this is the reason, you’ll see an x-CustomSpam header) option that you now want to disable in the spam filter that processed the message. How do we figure out which spam filter processed the message? Grab the message header and look for the following header.


This header will contain the name of the spam filter that was used to evaluate this message. As an example, I have the following spam filters configured in my Exchange Online tenant.

I sent a spam message to my own tenant and by looking at the headers I can see that my spam filter named “Who throws a shoe” was used for this message.

 SpamDiagnosticMetadata: Who+throws+a+shoe

Any other awesome headers?

Another handy header is X-MS-Exchange-AntiPhishPolicyId. If a message was marked as spam by your Phish policy, then this header will be present and contain the name of your Phish policy which processed the message.

Important stuff

From what I’ve seen, the above headers are only present in messages that have been marked as spam, and the component which was responsible for the spam determination is what will be present in the message header (ie. If the ATP Phish policy marked the message as phishing, then you’ll see X-MS-Exchange-AntiPhishPolicyId in the message header).

The above headers are subject to change at any point and may even be removed. But as of today, you can use them to make your troubleshooting adventures a little bit easier.

Cheers! 🍻