Laravel 12.48.1 / PHP 8.3.30 のプロジェクトで、メール認証(verification)の再送信が失敗しました。エラーは以下のような内容です。
Unable to connect with STARTTLS: … certificate verify failed
.env には Gmail SMTP を設定済み(例:MAIL_HOST=smtp.gmail.com / MAIL_PORT=587 / MAIL_ENCRYPTION=tls)でしたが、開発環境で一時的に MAIL_VERIFY_PEER=false を入れても改善しませんでした。結論から言うと、Laravel 12 では verify_peer / verify_peer_name を「SMTP設定の直下」に置かないと参照されないのが原因でした。
発生した症状と環境
- 環境:Laravel 12.48.1 / PHP 8.3.30
- 現象:メール認証の再送信で STARTTLS 接続が失敗
- エラー:
certificate verify failed系 - .env:Gmail SMTP(
smtp.gmail.com:587,tls)
(例:dummy@example.com)。
原因:Laravel 12では stream.ssl.* を見ていなかった
以前のプロジェクトの感覚で、config/mail.php(または関連設定)に SSL オプションを stream.ssl.verify_peer の形で書いていました。しかし Laravel 12 の Mailer は、この形式を参照してくれませんでした。
修正前(効かなかった形):
'smtp' => [
// ...
'stream' => [
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
],
],
],
この状態だと MAIL_VERIFY_PEER=false を入れても、期待通りに検証無効化が効かず、STARTTLS の証明書検証で落ち続けました。
修正:verify_peer / verify_peer_name を SMTP直下へ移動
Laravel 12 では、SMTP 設定の直下に verify_peer / verify_peer_name を置いたときだけ参照されます。そこで以下のように書き換えると、開発環境では MAIL_VERIFY_PEER=false で接続が通るようになりました。
修正後(効いた形):
'smtp' => [
'transport' => 'smtp',
'host' => env('MAIL_HOST'),
'port' => env('MAIL_PORT'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'verify_peer' => filter_var(env('MAIL_VERIFY_PEER', true), FILTER_VALIDATE_BOOLEAN),
'verify_peer_name' => filter_var(env('MAIL_VERIFY_PEER_NAME', true), FILTER_VALIDATE_BOOLEAN),
],
ポイントは「stream.ssl.* ではなく、smtp 配列の直下に置く」ことです。
ハマりどころ:.env変更後は config:clear を忘れない
Laravel は設定をキャッシュするため、.env を変えただけでは反映されないことがあります。今回も、値を変えたのに挙動が変わらず混乱しました。必ず次を実行します。
php artisan config:clear- (設定キャッシュ運用なら)
php artisan config:cache
また、MAIL_EHLO_DOMAIN が不正(例:空や変な文字列)だと、SMTP サーバ側で拒否されて失敗するケースもあるので注意しました。
教訓・注意点
- Laravel 12 では
verify_peer/verify_peer_nameの「置き場所」が重要(SMTP設定直下のみ参照) - .env を変えたら
php artisan config:clearをまず疑う - 開発では一時的に
MAIL_VERIFY_PEER=falseで切り抜けても、本番は基本trueに戻す(セキュリティ上の理由) MAIL_EHLO_DOMAINの値が適切かも併せて確認する

コメント