I'm trying to send an email using SwiftMailer (which is what Laravel uses by default):
$transport = (new Swift_SmtpTransport('smtp.my-server.com', 465, "tls"))
->setAuthMode('PLAIN')
->setUsername('my-username')
->setPassword('my-password');
$mailer = new Swift_Mailer($transport);
$message = (new Swift_Message('Wonderful Subject'))
->setFrom(['address@my-domain.com' => 'My Name'])
->setTo(['my-gmail-address@gmail.com'])
->setBody('Here is the message itself');
$mailer->send($message);
echo "\nMail sent! \n\n";
And running this gives me:
Expected response code 220 but got an empty response
Using the same settings in Thunderbird (an email client) works:
I'm able to send emails with these settings in Thunderbird. (from the same system I'm attempting to use swiftmailer)
So how can I debug this? Is there some default setting that I need to change in swiftmailer to make this work? Is there some way I can get more debug information?
My SMTP server doesn't even log an authentication attempt. It's like swiftmailer isn't even trying to connect to my smtp server!
UPDATE: I tried using Swift_Plugins_LoggerPlugin
to get more debugging info, but it was no help:
++ Starting Swift_SmtpTransport
!! Expected response code 220 but got an empty response (code: 0)
TLDR; use
ssl
instead oftls
when using a port that forcesssl/tls
. Swiftmailer's "tls" actually isn'ttls
, it'sstarttls
.
It seems that swiftmailer's "tls" encryption option is mislabeled! My server only accepts ssl/tls
on port 465, and I was able to connect to it over Thunderbird, but swiftmailer was unable to.
When I switched to port 587, which only supports starttls
on my server, it worked, even though the encryption is set to tls
(which should NOT be the same as starttls
).
Looking at the source files confirmed my suspicion:
if ($this->params['tls']) {
try {
$this->executeCommand("STARTTLS\r\n", [220]);
...
when it's set to tls
, it actually means starttls
. :P
So if you want to use ssl/tls
, do not use the swiftmailer encryption option "tls" 😅
When I changed the encryption to ssl
, it worked on the port that enforced ssl/tls
. So the answer is to use ssl
.
EDIT: I went to open an issue on the swiftmail github, but the issue was already there in "open" status. So I wasn't the only one to be bitten by this. 😛