Skip to content

SmtpTransport fails to detect broken socket and tries to reuse it infinitely #18968

@bugbreeder

Description

@bugbreeder

Description

We have a problem with sending emails. Our configuration uses an external SMTP server, i.e. transport configured to 'className' => 'Smtp'. We use the Queue system to send mails, but with a custom Job that basically calls
TransportFactory::get($transport)->send($message). (With some additional try/catch, logging and marking items as sent/done.)

The problem is that the mail server is a bit unreliable. The network connection sometime breaks, leading to the "SMTP Timeout" exception in _smtpSend. (Log mentions fwrite(): SSL: Broken pipe.) This in itself is a minor problem.

The big problem is that the SmtpTransport apparently does not detect that the connection is broken. When it is reused for the next mail it detects the apparently existing connection and tries to send a RSET. This fails, because the connection is already broken. Repeatedly. Apparently this connection is never cleaned up, rendering the SmtpTransport - which is infinitely reused by the factory - unable to send any other mail ever again. I need to manually restart the queue process to get it back to work.

At a first glance it looks that there is a try/catch missing or the isConnected method needs to be more thorough.

One workaround I'm going to try is calling an explicit disconnect() before (re)using the transport.

Important note: We currently use an older version of CakePHP and we need to upgrade eventually. But as far as I have checked the relevant code has not changed, so I expect the same problem to happen in the current 5.x branch.

CakePHP Version

4.3

PHP Version

8.2.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions