Extending SMTP timeout

Is there a way to extend the timeout interval when Discourse waits for the SMTP server to return the acknowledgment a email message has been submitted? Alternatively, is there a way to configure Discourse to not require this acknowledgment.

I’m experiencing a problem where my Discourse instance is generating duplicate emails. Discourse is receiving a Net::Timeout error when submitting emails for delivery. My Email provider is actually delivering the emails, but Discurse does not know this and proceeds to resend the emails. This repeats endlessly.

We recently added SMTP timeout customization, but that is about making the actual SMTP connection:

Sounds like your problem is after the connection is established and the problem is on the send transaction timeout?

2 Likes

Yes, as far as I can tell. The connection is established, the email message is submitted but there is a Net::Timeout error reported after that.

Using the discourse_doctor script, I see the message ID returned when the transition is successful and the Net::Timeout error when it fails.

This problem surfaced after updating to Discourse 2.9.0.beta5. I presume Discourse became less permissive of this error with that update.

I couldn’t find any related changes in the mail and net/smtp ruby gems. Maybe your SMTP server is misbehaving? Would be possible for you to migrate to another one?

1 Like

Thanks for checking. I agree, my Email provider seems to be the cause of the problem in the it is not responding quickly enough following an email submission. I can only summize that the problem is somehow load related in that some days I don’t experience the problem.

Changing Email providers is a significant challenge for a number of reasons. Finding a way to configure Discourse to work around this is the most attractive solution.

Moving to a new mail provider seems like the only solution to this issue, but that requires that I reconfigure the mail provider for my entire domain which is a task I would like to avoid.

Is there some change I can make the Discourse’s code handing outgoing mail to have it ignore mail submission failures, as it was doing in the past? I’m not a Rails dev, so I’m not sure where to even begin. I don’t want to break my ability to accept future Discourse updates.

What are you basing the above statement on? You can only really receive mail against one set of infra per domain/subdomain, but several services can relay email on its behalf.

Alternatively you could also spin up a new subdomain dedicated to your instance, which doesn’t even require a rebuild to configure.

I attempted this at one point in the past and misconfigured things and was not able to figure it out, hence my reluctance to change anything. I would also prefer the Discourse emails to originate from my company domain, but give that isn’t going to work any more I’ll try again to do as you suggest and use a subdomain for outgoing emails.

I’ve created a email subdomain using RackSpace Cloud and confirmed that I can send mail through it from my Mac using Apple Mail and curl. I’ve also confirmed I can send mail from my server using curl. However, I’m getting this error from discourse-doctor:

Testing sending to support@latenightsw.com using secure.emailsrvr.com:465, username:username with plain auth.
======================================== ERROR ========================================
                                    UNEXPECTED ERROR

Net::ReadTimeout

====================================== SOLUTION =======================================
This is not a common error. No recommended solution exists!

Please report the exact error message above to https://meta.discourse.org/
(And a solution, if you find one!)

My app.yml file contains these settings:

  DISCOURSE_SMTP_ADDRESS: secure.emailsrvr.com         # (mandatory)
  DISCOURSE_SMTP_PORT: 465                             # (optional)
  DISCOURSE_SMTP_USER_NAME: username      # (optional)
  DISCOURSE_SMTP_PASSWORD: password               # (optional, WARNING the char '#' in pw can cause problems!)

  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)
  

This matches the config documented here.

I’ve tried setting DISCOURSE_SMTP_ENABLE_START_TLS to false. Other posts for the Net::ReadTimeout error suggest trying this settings, but this made no difference:

  DISCOURSE_SMTP_AUTHENTICATION: "login"
  DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none

How can I diagnose this failure?

@Falco how do I make this change to my Discourse configuration? I cannot find any documentation for a setting I can add to my app.yml file.