Revisé recientemente los correos electrónicos: tarea y el código relacionado con el objetivo de probar cada una de las rutas de error y retocar el texto de error.
También descubrí que los efectos de establecer DISCOURSE_SMTP_ENABLE_STARTTLS=false son (en su mayoría) nulos. Establecer esto en realidad no deshabilitó STARTTLS y, de hecho, puede coexistir perfectamente con TLS en el momento de la conexión (DISCOURSE_SMTP_FORCE_TLS=true).
Sin embargo, antes de fusionar esto, creo que una advertencia para administradores en el panel cuando se establece DISCOURSE_SMTP_ENABLE_STARTTLS=false es adecuada. Me imagino que al menos un autoalojador lo ha configurado pero no lo necesita y en realidad depende de STARTTLS.
¡Eso suena a un buen trabajo! Una cosa que (creo que) he notado es que la tarea de rake en realidad no usa el mismo código que el envío real (como desde la página de prueba de correo electrónico de /admin/). Estoy bastante seguro de que he tenido un caso en el que funcionó en la UX pero no en la tarea de rake (¿o tal vez fue al revés?)
Mientras lo tienes fresco en mente, si pudieras asegurarte de que cuando realmente envía, lo hace utilizando el mismo código que usa Discourse, sería genial.
@supermathie, ¿vale la pena enviar un mensaje privado a todos los administradores de cada sitio que tenga esta variable configurada? Nuestro sistema actual de verificación de problemas lo hará, y no estoy seguro de que sea necesario aquí, dado que en la mayoría de los casos, esto tiene un efecto nil. Idealmente, querría mostrar esto solo en el panel de control sin notificar a los usuarios administradores, no estoy seguro de que nuestra estructura actual de verificación de problemas admita ese caso de uso.
Creo que sí: me parece extremadamente probable que, dada la confusión de muchos administradores con la configuración del correo electrónico, alguien tenga esta variable configurada cuando en realidad depende de starttls.
Probablemente nadie debería tenerla configurada.
Prefiero tener una advertencia espuria que romper silenciosamente la configuración de correo electrónico de alguien.
La alternativa es eliminar la verificación y neutralizar la variable para que no haga nada en absoluto.
Sería bueno que la advertencia no apareciera cuando el servidor SMTP saliente es localhost (es decir, coincide con el nombre de dominio de Discourse), ya que no se necesita TLS entre el contenedor Docker y el host, al ser la misma máquina.
Tuve el caso en la versión actual de que la línea comentada (el valor predeterminado es true) junto con force_tls impedía el envío de correos electrónicos. Así que la he descomentado y la he puesto en false. El envío de correos electrónicos ahora funciona, pero tengo este mensaje en el backend…
Depende un poco de en qué puerto se ejecute su proveedor de correo… no funcionan ambas cosas y definitivamente tienen un impacto.
También noté esto. Después de actualizar Discourse el 28 de noviembre, comencé a ver fallos en la entrega de correo con el mensaje de error Job exception: :enable_starttls and :tls are mutually exclusive. Set :tls if you're on an SMTPS connection. Set :enable_starttls if you're on an SMTP connection and using STARTTLS for secure TLS upgrade.
Backtrace
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/network/delivery_methods/smtp.rb:159:in `build_smtp_session'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/network/delivery_methods/smtp.rb:154:in `start_smtp_session'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/network/delivery_methods/smtp.rb:108:in `deliver!'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/message.rb:269:in `deliver!'
/usr/local/lib/ruby/3.3.0/delegate.rb:87:in `method_missing'
/var/www/discourse/lib/email/sender.rb:296:in `send'
/var/www/discourse/app/jobs/regular/user_email.rb:80:in `send_user_email'
/var/www/discourse/app/jobs/regular/user_email.rb:40:in `execute'
/var/www/discourse/app/jobs/base.rb:318:in `block (2 levels) in perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-7.0.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-7.0.0/lib/rails_multisite/connection_management.rb:17:in `with_connection'
/var/www/discourse/app/jobs/base.rb:305:in `block in perform'
/var/www/discourse/app/jobs/base.rb:301:in `each'
/var/www/discourse/app/jobs/base.rb:301:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:220:in `execute_job'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:185:in `block (4 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:180:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/suppress_user_email_errors.rb:6:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/discourse_event.rb:6:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/pausable.rb:131:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job/interrupt_handler.rb:9:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:26:in `track'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:134:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:173:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:184:in `block (3 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:145:in `block (6 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:118:in `local'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:144:in `block (5 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/config.rb:39:in `block in <class:Config>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:139:in `block (4 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:281:in `stats'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:134:in `block (3 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:133:in `block (2 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:85:in `global'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:132:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:40:in `prepare'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:131:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:183:in `block (2 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `block in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:86:in `process_one'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:76:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:10:in `watchdog'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:19:in `block in safe_thread'
Al igual que Johann Christoph, anteriormente tenía DISCOURSE_SMTP_ENABLE_START_TLS comentado y DISCOURSE_SMTP_FORCE_TLS establecido en true para TLS implícito y funcionaba de maravilla. Pero ahora tengo que establecer explícitamente DISCOURSE_SMTP_ENABLE_START_TLS en false para que la entrega de correo funcione, lo que por supuesto activa el mensaje mencionado en el panel de administración.
Será force_tls lo que impide el envío de correos electrónicos: esto fuerza TLS en el momento de la conexión y probablemente solo sea adecuado para el puerto 465.
¡Un unicornio!
¿Qué parámetros SMTP está utilizando (menos nombre de usuario/contraseña)?
Puerto 465 con ENABLE_START_TLS=false, FORCE_TLS=true y OPEN_TIMEOUT=10. Este último se debe a extraños errores de tiempo de espera que comencé a ver después de una actualización del sistema hace unos tres años, pero me cortaré la gorra si eso está relacionado con el problema descrito anteriormente.
Mientras tanto, eché un vistazo al historial de confirmaciones y noté que el gemmail se actualizó a la versión 2.9.0 solo tres días antes de la actualización que introdujo el problema de mi lado (#36254). Hay una entrada en las notas de la versión de eso que dice “SMTP: refactor and accept starttls :always and :auto by @eval in #1536”. No sé mucho sobre Ruby, pero este cambio en el PR referenciado me parece un poco sospechoso:
Dado que DISCOURSE_SMTP_ENABLE_START_TLS está documentado como verdadero por defecto (es decir, si está comentado), ¿es posible que esta sea la raíz del problema?
Para poder establecer DISCOURSE_SMTP_ENABLE_START_TLS en false, es necesario comentarlo, ya que de lo contrario está configurado en true por defecto. Precisamente eso fue lo que me causó el problema. Sin embargo, esto solo ocurrió con la última compilación (2025.12.0-latest).
¿Por qué demonios habrían hecho eso?
La dificultad aquí es que nunca deberíamos haber ofrecido esta configuración en primer lugar, debería haber sido algo como: