Email routing - Email is still forwarded, while being tagged as 'dropped'

Hi CF Community!

I created an email worker which I enabled for a destination email address:
The email worker will check if there is a certain keyword in the email title, and if so, it will block it (and if not, the mail is forwarded).

In the email routing activity log, I see that for most mails, the email is tagged as ‘dropped’. Yet these emails still end up in my [email protected] destination email address.

What is the logic behind this?

Welcome to the Cloudflare Community!

Currently, all mail handled by Workers is shown as dropped, no matter if you forward it or not. Workers a lso use Delivery failed if the worker errored out, ex:

Only mail forwarded by the normal route forward action is shown as “forwarded”

1 Like

Hello Chaika, and thanks for the welcome!

I was not aware that all email handled by a Worked is tagged as such.

All emails are shown as ‘dropped’, I do not have a ‘delivery failed’ for any of the mails in the list.

Currently, the code I use is the following:

export default {
async email(message, env, ctx) {
const block = “many spam words are listed here”
if (block.includes(message.headers.get(“from”)) == 1) {
message.setReject(“Address is blocked”);
} else {
await message.forward(“[email protected]”);

Any suggestions to ensure that ‘spam mails’ are no longer forwarded to the destination email address? Is this the correct method?

They are all correctly ending up in the destination spam folder (Microsoft 365), but I want to minimise the volume because there are legitimate emails in that folder from time to time.

Thanks for your help!

Keep in mind you’re filtering only on the from header, not the contents of the email or the subject

Forwarding unfortunately is prone to those kind of issues, if it’s important mail I would recommend not using email forwarding and instead using a full email setup like Microsoft’s 365 Business email (or however they bundle it so that you can use your custom domain for email).

You could try filtering out email based on the body and/or subject in a worker, but you’re not going to get everything, and email forwarding would still have the same issue with delivery.

1 Like

Thanks for the insights!

Indeed, I search for words in the sender name. The spam we receive is almost always very similar over time (for example, we would receive daily a spam mail ‘lottery winner’).

It’s a pity the forward service cannot be customised with a Worker to effectively manage email flows to the destination email address.
Unless there are other ways to do this within Cloudflare?

Actually the second evolution I had in mind was to allow forwarding mails to multiple destination email addresses ([email protected] arrives in 3 destination mailboxes).
Possible Workers are limited as well in that regard?

I may have misunderstood you originally, you absolutely can reject the mail that way (set reject), and they won’t be forwarded. I understood it as you were saying some legitimate mail was being spammed by Microsoft as well, which if so is just an issue with the practice of forwarding in general:

If you are still receiving the mail, your worker is not rejecting it. It will always be “dropped” regardless if your worker rejected it, or if it forwarded it. Your current match is checking if the email from header is contained in block. The email from header is formatted like "Cloudflare <[email protected]>"

The part first being the optional display name, and the later being the email address.

Your current code would only work if your block list contained the exact display name and address. If you wanted it to reject if the from header contained any bad word like “lottery winner” at all, you’d want something like

let block = ["lottery winner", "bad", "malicious"]; // spam words as array
if (block.some(word => message.headers.get("from").includes(word))) 

You can forward to multiple destinations with workers no problem – just call the message.forward method repeatedly. They do all have to be verified addresses though.