Description
Laravel Version
12.17.0
PHP Version
8.3.7
Database Driver & Version
No response
Description
I discovered this using the Postmark driver, but it looks like it could affect Mailgun and the other API-based drivers as well. I'm also using the Redis queue driver.
I'm trying to send a Notification via the mail channel to an email address that Postmark considers "inactive". Instead of a proper error response, I get the following exception:
[2025-06-16 21:58:21] production.ERROR: Cannot serialize Symfony\Component\HttpClient\Response\CurlResponse {"exception":"[object] (BadMethodCallException(code: 0): Cannot serialize Symfony\\Component\\HttpClient\\Response\\CurlResponse at /vendor/symfony/http-client/Response/CommonResponseTrait.php:124)
[stacktrace]
#0 [internal function]: Symfony\\Component\\HttpClient\\Response\\CurlResponse->__sleep()
#1 /vendor/laravel/framework/src/Illuminate/Queue/Queue.php(172): serialize()
#2 /vendor/laravel/framework/src/Illuminate/Queue/Queue.php(140): Illuminate\\Queue\\Queue->createObjectPayload()
#3 /vendor/laravel/framework/src/Illuminate/Queue/RedisQueue.php(231): Illuminate\\Queue\\Queue->createPayloadArray()
#4 /vendor/laravel/horizon/src/RedisQueue.php(89): Illuminate\\Queue\\RedisQueue->createPayloadArray()
#5 /vendor/laravel/framework/src/Illuminate/Queue/Queue.php(112): Laravel\\Horizon\\RedisQueue->createPayloadArray()
#6 /vendor/laravel/horizon/src/RedisQueue.php(47): Illuminate\\Queue\\Queue->createPayload()
#7 /vendor/laravel/framework/src/Illuminate/Queue/Queue.php(63): Laravel\\Horizon\\RedisQueue->push()
#8 /vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(636): Illuminate\\Queue\\Queue->pushOn()
#9 /vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(555): Illuminate\\Events\\Dispatcher->queueHandler()
#10 /vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(481): Illuminate\\Events\\Dispatcher->Illuminate\\Events\\{closure}()
#11 /vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(288): Illuminate\\Events\\Dispatcher->Illuminate\\Events\\{closure}()
#12 /vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(268): Illuminate\\Events\\Dispatcher->invokeListeners()
#13 /vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php(110): Illuminate\\Events\\Dispatcher->dispatch()
#14 /vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(169): Neves\\Events\\TransactionalDispatcher->dispatch()
The actual error message from Postmark was completely missing. When the Postmark driver doesn't receive a 200 response, it throws a Symfony\Component\Mailer\Exception\HttpTransportException
that contains the Symfony\Component\HttpClient\Response\CurlResponse
object. Laravel then catches this exception in \Illuminate\Notifications\NotificationSender::sendToNotifiable
and tries to dispatch a NotificationFailed
event containing the HttpTransportException
. When Laravel tries to serialize the event to place on the queue, the above error message is thrown.
Proposal: In NotificationSender
, if a HttpTransportException
is caught, don't include it in the NotificationFailed
event. Instead, create a generic Symfony\Component\Mailer\Exception\TransportException
without the response object, but containing the message from the HttpTransportException
. e.g. $exception = new TransportException($exception->getMessage(), $exception->getCode())
. This way the NotificationFailed
event will dispatch correctly, and the HttpTransportException
will appear in the logs (if the user doesn't catch it).
I think this could be a breaking change for someone using the sync
queue driver and doing something with the response object in a NotifictionFailed
handler.
For reference, here's what that error message actually looks like:
Symfony\Component\Mailer\Exception\HttpTransportException(code: 0): Unable to send an email: You tried to send to recipient(s) that have been marked as inactive. Found inactive addresses: xxx@yyy.zzz. Inactive recipients are ones that have generated a hard bounce, a spam complaint, or a manual suppression. (code 406). at /vendor/symfony/postmark-mailer/Transport/PostmarkApiTransport.php:91
I will submit a PR with this fix, but am interested in any alternate solutions.
Steps To Reproduce
- Install and configure Postmark mail driver
- Try to send a Notification on the mail channel to an "inactive" email address
- "Cannot serialize CurlResponse" error thrown