In-depth Analysis and Solution for Swift_TransportException: Expected response code 220 but got code \"\" in Laravel Mail Sending

Dec 01, 2025 · Programming · 14 views · 7.8

Keywords: Laravel | SwiftMailer | Gmail SMTP | Two-Step Verification | App Password

Abstract: This article provides a comprehensive exploration of the common error \"Expected response code 220 but got code \"\"\" encountered when using SwiftMailer for email sending in the Laravel framework. It begins by analyzing the root cause of this error—SMTP connection failures, particularly authentication issues with Gmail services. The article then details the complete process of enabling Gmail two-step verification and generating app-specific passwords, including proper configuration of .env and mail.php files. Additionally, it covers alternative port and encryption protocol solutions and offers best practices such as configuration cache clearing. Through code examples and step-by-step guidance, it helps developers resolve email sending issues effectively.

In Laravel development, email sending is a common requirement, but developers often encounter the Swift_TransportException with the error message Expected response code 220 but got code \"\". This error indicates a failure in establishing a connection with the SMTP server, typically due to authentication or configuration issues. This article delves into the causes of this error and presents solutions based on best practices.

Error Cause Analysis

When Laravel attempts to send an email via SwiftMailer, it establishes a connection with the configured SMTP server. The response code 220 is the standard SMTP protocol indicator that the server is ready. An empty response (code \"\") usually signifies that the connection failed at the initial stage. With Gmail as the SMTP server, this is often caused by not enabling two-step verification or using an incorrect password.

Solution: Enable Gmail Two-Step Verification and App Password

Gmail requires applications sending emails to use app-specific passwords instead of regular account passwords. First, visit the Google App Passwords page to enable two-step verification. After enabling, generate an app-specific password. Next, update Laravel's configuration files.

Configuring the .env File

In the .env file at the project root, set the following parameters:

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password
MAIL_ENCRYPTION=tls

Here, MAIL_PASSWORD should use the generated app-specific password, not the account password.

Configuring the mail.php File

In config/mail.php, use environment variables to dynamically load configurations:

<?php

return [
    'driver' => env('MAIL_DRIVER', 'smtp'),
    'host' => env('MAIL_HOST', 'smtp.gmail.com'),
    'port' => env('MAIL_PORT', 587),
    'from' => ['address' => env('MAIL_FROM_ADDRESS', 'your-email@gmail.com'), 'name' => env('MAIL_FROM_NAME', 'Your Name')],
    'encryption' => env('MAIL_ENCRYPTION', 'tls'),
    'username' => env('MAIL_USERNAME'),
    'password' => env('MAIL_PASSWORD'),
    'sendmail' => '/usr/sbin/sendmail -bs',
    'pretend' => false,
];

This approach enhances configuration flexibility and security.

Alternative Configuration Options

If issues arise with TLS encryption and port 587, try using SSL encryption with port 465. Set in the .env file:

MAIL_PORT=465
MAIL_ENCRYPTION=ssl

This may work in certain network environments or specific Gmail settings. However, TLS with port 587 is generally the recommended standard.

Clearing Configuration Cache

After modifying configuration files, run the following Artisan commands to ensure changes take effect:

php artisan config:cache
php artisan config:clear

This clears old configuration caches and reloads the new settings.

Code Example

The code for sending emails in a controller should remain concise:

use Illuminate\Support\Facades\Mail;

Mail::send('sendMail', ['key' => 'value'], function($message) {
    $message->to('recipient@example.com', 'Recipient Name')
            ->subject('Welcome!');
});

Ensure the view file sendMail.blade.php exists and contains correct HTML or plain text content.

Conclusion

The key to resolving the Expected response code 220 but got code \"\" error lies in properly configuring Gmail two-step verification and app passwords. By updating the .env and mail.php files and clearing configuration caches, email sending functionality can be restored. Developers should choose between TLS or SSL encryption based on actual needs and follow best practices to enhance application security.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.