# Bounced emails not being detected

**URL:** https://meta.discourse.org/t/bounced-emails-not-being-detected/293518
**Category:** Support
**Tags:** email
**Created:** [January 30, 2024, 6:36pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518 "2024-01-30T18:36:10Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [January 30, 2024, 6:36pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/1 "2024-01-30T18:36:10Z")

</div>

I’m trying to figure out how to get discourse to clean up email lists, specifically bounced emails. The site is using a private smtp server to send emails but the response is set to came back to a gmail address for POP access by discourse.

So I see bounced emails in the _Received_ emails dashboard.

 ![image](https://global.discourse-cdn.com/meta/original/4X/1/b/c/1bcd817dc89cee0a19832c7c563db3ebf69d3145.png)

However under the _Bounced_ emails dashboard, there’s nothing

 ![image](https://global.discourse-cdn.com/meta/original/4X/f/8/1/f81aad794821001f6c32a1e80ebb2257bf0fd0bd.png)

When I look at the Discourse error logs, I do see that it’s detecting a bounced email

> **Email can not be processed: Email::Receiver::BouncedEmailError**
> 
> Delivered-To: [xxx.yyy@gmail.com](mailto:xxx.yyy@gmail.com)  
> Received: by 2002:xxx:7022:911:xx:73:xxx:f96 with SMTP id xxx7csp1115046dlb;  
> Thu, 25 Jan 2024 12:03:33 -0800 (PST)  
> X-Google-Smtp-Source: AGHT+IEagzW8QOUgAyfOxU9wYaox/wuiL/wNqWhvftUB4uO/85r9H/55+FnfT6NrSTkLI5kfj+Vy  
> X-Received: by 2002:xxx:620a:4xxx:b0:xxxx:9265 with SMTP id br34-xxx8ba09265mr280168qkb.77.17062130xxx;  
> Thu, 25 Jan 2024 12:03:33 -0800 (PST)  
> Return-Path: \<\>  
> Received: from [xxx.com](http://xxx.com) ([xxx.com](http://xxx.com). [207.xxx.xxx.xxx])  
> by [mx.google.com](http://mx.google.com) with ESMTPS id bi4-xxx0b00783c84e9ef8si590747qkb.206.xxx.01.xx.12.03xxx  
> for [xxx.yyy@gmail.com](mailto:xxx.yyy@gmail.com)  
> (version=TLS1\_3 cipher=TLS\_AES\_256\_GCM\_SHA384 bits=256/256);  
> Thu, 25 Jan 2024 12:03:33 -0800 (PST)  
> Received-SPF: none ([google.com](http://google.com): [xxx.com](http://xxx.com) does not designate permitted sender hosts) client-ip=207.xxx.xxx.xxx;  
> Authentication-Results: [mx.google.com](http://mx.google.com);  
> dkim=pass [header.i=@xxx.co.nz](mailto:header.i=@xxx.co.nz) header.s=alpha header.b=biFVvXep;  
> arc=fail (signature failed);  
> spf=none ([google.com](http://google.com): [xxx.com](http://xxx.com) does not designate permitted sender hosts) [smtp.helo=xxx.com](http://smtp.helo=xxx.com);  
> dmarc=pass (p=NONE sp=REJECT dis=NONE) [header.from=xxx.co.nz](http://header.from=xxx.co.nz)  
> Received: from [xxx.co.nz](http://xxx.co.nz) ([xxx.co.nz](http://xxx.co.nz) [210.xxx.xxx.5x])  
> by [xxx.com](http://xxx.com) (Postfix) with ESMTP id 4DD66xxx8E3  
> for [xxx@zzz.com](mailto:xxx@zzz.com); Thu, 25 Jan 2024 20:03:28 +0000 (UTC)  
> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; [d=zzz.com](http://d=zzz.com);  
> s=dkim; t=1706213008;  
> h=from:from:reply-to:subject:subject:date:date:message-id:message-id:  
> to:to:cc:mime-version:mime-version:content-type:content-type:  
> dkim-signature;

So the question is

1. Why isn’t discourse marking bounced emails as bounced and how do I correct this?

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [January 30, 2024, 6:51pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/2 "2024-01-30T18:51:44Z")

</div>

Discourse uses the `reply_key` to associate bounces with sent emails. When Discourse sends mail, it uses the `reply_by_email_address` value as the SMTP envelope sender.

You need to ensure your `reply_by_email_address` includes a `{reply_key}` so your instance can associate the bounces with the correct sent mail.

For instance, here on meta it’s set to `incoming+%{reply_key}@meta.discoursemail.com` and anything set to that address gets delivered to this instance.

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [January 30, 2024, 7:07pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/3 "2024-01-30T19:07:39Z")

</div>

Thanks for the response. Unfortunately I’ve had to turn off the `reply_key` from the response to email because on our email relay server doesn’t recognize the `+` addressing. Is there any other option?

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [January 30, 2024, 7:11pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/4 "2024-01-30T19:11:26Z")

</div>

> [@RBoy](#):
>
> email because on our email relay server doesn’t recognize the `+` addressing

Your email relay server shouldn’t matter, only the end server where the mailbox lies. Email localparts are opaque to any intermediate servers.

Is it not gmail as per:

> [@RBoy](#):
>
> Delivered-To: [xxx.yyy@gmail.com](mailto:xxx.yyy@gmail.com)

* * *

> [@RBoy](#):
>
> Is there any other option?

I’m not sure if we have another mechanism to reliably detect bounces.

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [January 30, 2024, 7:23pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/5 "2024-01-30T19:23:19Z")

</div>

Okay to clarify, the destination SMTP domain server which receives the bounced email doesn’t recognize the `+` addressing, so it only forwards emails based on the `To` field to the gmail address which is picked up by discourse via POP. That if the `To` field includes the `reply_key` then it won’t forward that email to the gmail account used by discourse.

So I can’t put the `reply_key` in the email address, can it put somewhere else? In the subject field or body or somewhere where discourse may be able to parse it?

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [January 30, 2024, 7:39pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/6 "2024-01-30T19:39:38Z")

</div>

> [@RBoy](#):
>
> the destination SMTP domain server which receives the bounced email doesn’t recognize the `+` addressing, so it only forwards emails based on the `To` field to the gmail address which is picked up by discourse via POP

It would help a **lot** if you wrote what you were actually using for settings, even anonymised slightly.

You might also want to look into setting `alternative_reply_by_email_addresses`.

> [@RBoy](#):
>
> can it put somewhere else?

I don’t believe so.

If possible, for your setup I’d recommend something like:

- set `reply_by_email_address` to `inbound+%{reply_key}@forum.hostname`
- configure a mail server to receive email for `forum.hostname` and deliver it all to `the.gmail.account@gmail.com`

Here the intermediate mail server doesn’t need to understand plus-addressing, it just needs to forward on everything for the domain.

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [January 30, 2024, 8:13pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/8 "2024-01-30T20:13:18Z")

</div>

Absolutely

Email parsing setup:

 ![image](https://global.discourse-cdn.com/meta/original/4X/4/3/6/436c1d6e0df407f88d6c99cdf93fc558d4b05a5b.png)

Email sending setup:

 ![image](https://global.discourse-cdn.com/meta/original/4X/f/f/8/ff86970f4e866212f9e7911385397205beee37fe.png)

- The email sent by Discourse goes from `discourse@xxx.com` via a dedicated domain SMTP server setup for discourse (using the discourse domain address).
- Any replies or when email bounces back, the domain SMTP server forwards the email to `discourse.xxxx@gmail.com`. This domain SMTP server cannot recognize the `+` addressing, so if I include the `reply_key` in the reply to email address, it’ll get dropped by the domain SMTP server. I can only set rules to forward discrete/unique incoming email addresses.
- The discourse forum then uses POP via GMail to access those forwarded replies/bounced emails and parses them.

Does this help?

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [January 30, 2024, 9:07pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/10 "2024-01-30T21:07:27Z")

</div>

I understand what you’re saying. Unfortunately due to a limitation of the SMTP server rules I cannot setup forwarding for sub domains, I can only configure it to forward unique `To` emails id’s.

However I have a clarification here - more like a discrepancy in how discourse appears to be working:

1. When a user replies to an email post, it comes in correctly - replies seem to work perfectly even without any `{reply_key}` explicitly configured anywhere (see the screenshots above)
2. However, when an email gets bounced, Discourse categorizes it under _Received_ rather than _Bounced_
3. **The error logs are showing that something in discourse recognizes that it’s a bounced email** (see my first post error log). So if something in discourse is recognizing that it’s a bounced email, why doesn’t is show up under _Bounced_ instead of _Received_?

So why is that when a user replies to a post it is processed correctly by discourse but not a bounced email (and there also appears to be a disconnect between the error logs and the dashboard for bounced emails). Am I missing something in the configuration?

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [January 30, 2024, 9:30pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/11 "2024-01-30T21:30:05Z")

</div>

I’ve also tried setting the `reply by email address` settings in discourse to `discourse.xxx+%{reply_to}@gmail.com` but then when the email gets delivered, gmail seems to think that the domain [yyy.com](http://yyy.com) (discourse SMTP domain) is trying to spoof the gmail domain and it ends up marking it as spam. It appears that setting a reply to domain different from the senders domain is triggering a DMARC and SPF failure.

```plaintext
ARC-Authentication-Results: i=1; mx.google.com;
       spf=softfail (google.com: domain of transitioning discussion.xxx+verp-b9c40db917ca04993dd3433cc9748518@gmail.com does not designate y.y.y.y as permitted sender) smtp.mailfrom=discussion.xxx+verp-b9c40db917ca04993dd3433cc9748518@gmail.com;
       dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yyy.com
Return-Path: <discussion.xxx+verp-b9c40db917ca04993dd3433cc9748518@gmail.com>

```

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [February 6, 2024, 6:48pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/12 "2024-02-06T18:48:08Z")

</div>

> [@RBoy](#):
>
> So why is that when a user replies to a post it is processed correctly by discourse but not a bounced email (and there also appears to be a disconnect between the error logs and the dashboard for bounced emails).

You’ve turned off `find related posts with key` (I hope you read the warning) thus Discourse is using the `in-reply-to` mail header to determine to which topic/post the reply should be referencing.

It can’t do that for bounces - Discourse **needs** to know the specific message which bounced and that information is only guaranteed to be in one spot - the `To:` address (which comes from the envelope-from address of the original message).

For this to work, when Discourse sends a message, it needs to receive the reply to the address from which it came. Discourse looks in the `To:` header for this (not the envelope-to).

> [@RBoy](#):
>
> is trying to spoof the gmail domain

_is_ spoofing the gmail domain

> [@RBoy](#):
>
> It appears that setting a reply to domain different from the senders domain is triggering a DMARC and SPF failure.

If you want to send mail from a gmail address, you need to send it via their servers. But [they don’t like that](https://meta.discourse.org/t/setting-up-discourse-using-gmail-smtp-settings/291749/2).

> [@RBoy](#):
>
> ```plaintext
> ARC-Authentication-Results: i=1; mx.google.com;
> spf=softfail (google.com: domain of transitioning discussion.xxx+verp-b9c40db917ca04993dd3433cc9748518@gmail.com does not designate y.y.y.y as permitted sender) smtp.mailfrom=discussion.xxx+verp-b9c40db917ca04993dd3433cc9748518@gmail.com;
> dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yyy.com
> Return-Path: <discussion.xxx+verp-b9c40db917ca04993dd3433cc9748518@gmail.com>
> 
> ```

Doesn’t look like you’ve configured DKIM for `yyy.com`; you should do that. If you get that right, DMARC should pass.

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [February 6, 2024, 10:14pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/13 "2024-02-06T22:14:31Z")

</div>

> [@supermathie](#):
>
> Doesn’t look like you’ve configured DKIM for `yyy.com`

Yes it’s configured and the email “sent” by discourse via the `yyy.com` SMTP server passes SPF, DKIM and DMARC without issues (atleast from the “Send test email” page in the admin console).

This issue is happening if I set a gmail address as the `reply_by_email_address` to a `gmail.com` address instead of the `yyy.com` address. Is there something I can do for this setup so that DMARC doesn’t fail when set to `reply_by_email_address` to a gmail address while keeping the outgoing server as `yyy.com` ?

> [@supermathie](#):
>
> For this to work, when Discourse sends a message, it needs to receive the reply to the address from which it came. Discourse looks in the `To:` header for this (not the envelope-to).

Can it not parse the rest of the content/attachments in the bounced email to extract that information if it can’t what it need in the “obvious” place (or atleast provide an option in settings to do that with the necessary warnings about impersonation)

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [February 6, 2024, 10:41pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/14 "2024-02-06T22:41:57Z")

</div>

> [@RBoy](#):
>
> Is there something I can do for this setup so that DMARC doesn’t fail when set to `reply_by_email_address` to a gmail address while keeping the outgoing server as `yyy.com` ?

DMARC alignment fails since the `reply_by_email_address` is used as the envelope-from address in this situation.

> [@RBoy](#):
>
> Can it not parse the rest of the content/attachments in the bounced email to extract that information if it can’t what it need in the “obvious” place (or atleast provide an option in settings to do that with the necessary warnings about impersonation)

Pretty much the _only_ thing guaranteed to be intact on a bounce is the address.

_Maybe_ the subject, but it would not be practical to put this information there.

I do see that some systems include the original message as an attachment… it’s theoretically possible that we could check bounces for an attachment to get more information if they exist.

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [February 6, 2024, 10:55pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/15 "2024-02-06T22:55:13Z")

</div>

> [@supermathie](#):
>
> DMARC alignment fails since the `reply_by_email_address` is used as the envelope-from address in this situation.

If I’m understanding this correctly, the `reply_by_email_address` should be set in the `reply-to` field of the envelope sent by the Discourse (from [yyy.com](http://yyy.com)). So when the user replies, they [reply to](https://mailtrap.io/blog/email-headers/) the `reply-to` email ([gmail.com](http://gmail.com)) rather than the original ([yyy.com](http://yyy.com)) address. So in the email response envelope, the `from` address should be the users email address and the `to` is the [gmail.com](http://gmail.com) address.

Why would the `reply_by_email_address` be used as the `from` address?

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [February 6, 2024, 11:01pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/16 "2024-02-06T23:01:44Z")

</div>

> [@RBoy](#):
>
> Why would the `reply_by_email_address` be used as the `from` address?

the `reply_by_email_address` is not used as the from address but the envelope-from, specifically so bounces work

Here’s an image that demonstrates how each address is used. The addresses themselves are specific to our hosting, but should be sufficient for an example.

```plaintext
notification_email: notifications@hs1.discoursemail.com
reply_by_email_address: incoming+%{reply_key}@hs1.discoursemail.com

```

A notification:

 ![image](https://global.discourse-cdn.com/meta/original/4X/4/6/d/46daa36c80253ba591caf1ce3018c7f0c6d936a3.png)

A replyable message:

 ![image](https://global.discourse-cdn.com/meta/original/4X/3/4/3/3439fe46ead24e71ca18dbb39d67e80b72431077.png)

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [February 7, 2024, 1:19am UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/17 "2024-02-07T01:19:15Z")

</div>

Thanks. That’s super helpful.

So basically the `reply_by_email_address` is used in the from header so that it comes back to that email address if it bounces. And the same email address is also set on the reply-to header if replies by email are enabled.

So, if my understanding above is correct, then if discourse can have a separate setting (`reply_to_email`) for the `reply-to` header, then that would solve the issue for the DMARC failure. When using the [yyy.com](http://yyy.com) domain (taken from `reply_by_email_address`) for `from` while sending and [gmail.com](http://gmail.com) for the `reply-to` (taken from the a new `reply_to_email` setting). If the email bounces it will still be returned to the `reply_by_email_address` but if the user replies then it would go to `reply_to_email`.

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [February 7, 2024, 2:17am UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/18 "2024-02-07T02:17:25Z")

</div>

> [@RBoy](#):
>
> So basically the `reply_by_email_address` is used in the from header so that it comes back to that email address if it bounces.

That’s the SMTP `envelope-from`, not the `From` header. The `From` header is not used for bounces.

i.e. ① not ②:

 ![image](https://global.discourse-cdn.com/meta/original/4X/e/8/8/e88b77cf98ea663da4461e135569e5f771d1f4b8.png)

> [@RBoy](#):
>
> So, if my understanding above is correct, then if discourse can have a separate setting (`reply_to_email`) for the `reply-to` header, then that would solve the issue for the DMARC failure.

To pass DMARC, either the SPF (which validates the envelope-from in combination with the sending IP) or DKIM (which validates the From and checksums fields of the message) have to [align](https://dmarcian.com/alignment/).

It sounds like the whole point of this exercise is to have a “pretty” reply-to address, that users reply to?

You want something like this?

```plaintext
envelope-from: outgoing+12309847801923840923502389423@yyy.com
…
From: notifications@yyy.com
To: user@contoso.com
Reply-to: my_sweet_forum+12309847801923840923502389423@gmail.com

```

You _must_ have that envelope-from like so, or bounces _will not work_.

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [February 7, 2024, 2:06pm UTC](https://meta.discourse.org/t/bounced-emails-not-being-detected/293518/19 "2024-02-07T14:06:15Z")

</div>

> [@supermathie](#):
>
> It sounds like the whole point of this exercise is to have a “pretty” reply-to address, that users reply to?
> 
> You want something like this?
> 
> ```plaintext
> envelope-from: outgoing+12309847801923840923502389423@yyy.com
> …
> From: notifications@yyy.com
> To: user@contoso.com
> Reply-to: my_sweet_forum+12309847801923840923502389423@gmail.com
> 
> ```

Yes, that’s correct. The idea to have the `envelope-from` different from the `reply-to`.

Since the `envelope-from` domain and the sending IP match, the SPF should pass but at the same time the reply can go to GMail to process responses and if the email should bounce it’ll head back to the original domain server which can then forward the bounce back to the GMail inbox as well.

It would actually look like this:

```plaintext
envelope-from: outgoing@yyy.com
…
From: notifications@yyy.com
To: user@contoso.com
Reply-to: my_sweet_forum+12309847801923840923502389423@gmail.com

```

In my setup the outgoing won’t have a VERP because my incoming SMTP doesn’t support VERP (i.e. the bounce back won’t have a VERP address), that’s why the `reply-to` is being sent to GMail because it supports VERP. This shouldn’t cause a DMARC failure as it does right now.
