I'm also experiencing this issue. Do you have a current workaround?
laravel swift-mailer exception “Expected response code 250 but got an empty response” using gmail smtp-relay (database queue driver)
the gmail smtp-relay works fine using the sync driver, but if we queue the email we this error. cleared config, cache, & restarted queue workers. tested in prod and dev, same results
[2021-01-24 20:04:22] production.ERROR: Expected response code 250 but got an empty response {"exception":"[object] (Swift_TransportException(code: 0): Expected response code 250 but got an empty response at /home/****/****/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php:448)
were wondering is this because of serialization and something is not making it through that process??? using latest stable release of laravel >8.0. gmail smtp is authenticating just fine, per why the sync driver sends emails easily. maybe there needs to be a timeout on the queue jobs so they dont barrage gmail so quickly? also our code works fine using sendgrid for example as the smtp relay. thanks.
I had this and it was related to the CLI installation of PHP not having the required SSL drivers enabled.
It works fine in SYNC because php-fpm is doing the communications with the remote mail server, but your queue workers are running under cli php
thanx for the answer but I dont really know how to fix it like that
Found a Solution that works for me. Try this one.
Update your AppServiceProvider.php
add this inside boot();
// Fix for SwiftMailer Service; $_SERVER["SERVER_NAME"] = "your.domain.name";
Seems so gmail does not want too many emails coming from 127.0.0.1 and by default the php-cli will send 127.0.0.1 because SERVER_NAME is not defined. Swift is getting this value and if empty sets it to 127.0.0.1
It worked man. Thats so weird. You think thats the best place to set the $_SERVER['SERVER_NAME'] variable? Couldn't we set it config/app.php via an env()? THanks for the reply
I'm not sure about placing that inside app.php. With what I understand is that it returns an array of values for the config() helper but does not set things inside the $_SERVER global variable and it's native to the app and not global. So I assumed that it is best placed in the boot of the APP so that I'm sure the SERVER_NAME is set before anything else. I'm just lazy to bootstrap it as a hook before an email sends. I know it's not elegant but works for me. haha!
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
'Illuminate\Mail\Events\MessageSending' => [
'App\Listeners\SetDomainForSmtp',
],
];
@fallenknight85 based on what you taught me i came up with this event driven method.
add this to your event service provider, in the boot() for the listener (i made mine SetDomainForSmtp) you can set the global $_SERVER['SERVER_NAME'] in response to an email being sent. this hooks into the event before so its perfect for avoiding setting the global on other request-response cycles. seems to work great
dude I tried your suggestion but I experienced again the issues with SMTP. I reverted back to appserviceprovider.php
should work once the cache is cleared?
this is my listener class
<?php
namespace App\Listeners;
use Illuminate\Mail\Events\MessageSending;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class SetDomainForSmtp
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param MessageSending $event
* @return void
*/
public function handle(MessageSending $event)
{
$_SERVER['SERVER_NAME'] = config('app.mail_domain') ?? '127.0.0.1';
}
}
the event provider class
<?php
namespace App\Providers;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
use App\Matter;
use App\User;
use App\Observers\MatterObserver;
use App\Observers\UserObserver;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
'Illuminate\Mail\Events\MessageSending' => [
'App\Listeners\SetDomainForSmtp',
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
Matter::observe(MatterObserver::class);
User::observe(UserObserver::class);
}
}
You can set SERVER_NAME= directly in your env file.
then opening tinker and >>> $_SERVER the name will be listed in the variables echoed
im gonna give that a try
This can be an issue when the server cannot resolve its own name.
Normally fix this by an entry in \etc\hosts
that would be \etc\hosts for the entire server right? i had some entries mapped to it already but not my domain. im not super advanced in linux. @snapey have you tried this or have any tips for it? our server is provisioned via forge and it wont be multisite but you think it would cause any issues trying it?
Hi All, I have exactly the same issue. Does anyone know if there is a better solution?
Thanks
I put this code in AppServiceProvider inside boot function:
$_SERVER['SERVER_NAME'] = gethostname();
Please refer to php official website for supported PHP version of gethostname function.
👍
Will that work when running under PHP CLI?
I tried on php artisan command, and it works...
Please advice, you must set your server hostname with Fully Qualifed Domain Name.
@metasanjaya This works for me, tks!
First, sorry for reviving the post.
I'm having the same problem as OP, setting the SERVER_NAME as suggested is not working for me and I tested the variable creating a log before sending the email and it's correct. Weird because it was working fine a few hours ago, and now it broke, and I didn't change the code. Also running it on queue, but sync works. Has anyone else got any idea or found a solution for this case?
@lucasjose501 Please did you finally solve the issue? Kindly share with me what you did
@lucasjose501 Still the solution is working on my side. If you're using Laravel 9, you may want to also configure MAIL_EHLO_DOMAIN="<your_domain>", also be sure that you are using the correct encryption for the specified port. Usually, if MAIL_PORT=587, your MAIL_ENCRYPTION=tls, whereas, MAIL_PORT=465 is MAIL_ENCRYPTION=ssl.
IF you are using SMTP Relay, ensure both IPv4 and IPv6 of the host containing the App are whitelisted on the RELAY host.
SYNC method works perfectly. for QUEUES, on experience, REDIS QUEUE on Ubuntu 22.04, I have to run PHP artisan optimize to make it work.
This happens when your connection to the Internet is poor.
I have a very similar problem and don't know how to fix it!
I created a temporary mail in (Google Workspace) and connected everything to the test site, but when sending an email from the site I get an error (Expected response code "250" but got an empty response.)
Here is the code from file .env
MAIL_MAILER=smtp
MAIL_HOST=smtp-relay.gmail.com
MAIL_PORT=465
[email protected]
MAIL_PASSWORD=password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="[email protected]"
MAIL_FROM_NAME="${APP_NAME}"
And here is the controller
$email_admin = "[email protected]";
$to_name = 'Reservation';
$to_email = '[email protected]';
$to_client_email = $request->email;
Mail::send('mail', compact('reservations'), function ($message) use ($reservations, $to_email) {
$message->from("[email protected]", 'username');
$message->to($to_email)->subject('laravel reservation');
});
$repsond=Mail::send('mail_client', compact('reservations'), function ($message) use ($reservations, $to_client_email) {
$message->from("[email protected]", 'username');
$message->to($to_client_email)->subject('laravel reservation client');
});
@viktor3177 If it's possible on your Google Workspace SMTP Relay configuration, use the IP Authentication instead of the SMTP Auth. If you are using SMTP Auth, be sure that the MAIL_USERNAME exists in the Directory and if 2FA is enabled you cannot use the Account Password. Instead, it would be best to generate an App Password for the SMTP Auth Account. The password that you are going to use is the generated app password. Also take note that smtp-relay.gmail.com uses port 587 for MAIL_PORT. If using IP Auth, keep MAIL_USERNAME, MAIL_PASSWORD to null.
Please or to participate in this conversation.