Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

KeithBrink's avatar

Laravel Horizon: ErrorException: Warning: PDO::prepare(): MySQL server has gone away

  • Laravel Version: 5.7.28
  • PHP Version: 7.2.15
  • Database Driver & Version: MariaDB 10.2.23

I am struggling with a bug on my production server using Horizon.

ErrorException: Warning: PDO::prepare(): MySQL server has gone away [internal] in unserialize

You can see a stack trace of the error here: https://sentry.io/share/issue/b105b7946b524a9e841f56f44445ea14/

As far as I can tell, this error should be caught by the Laravel framework. I'm not sure why it's not being caught and turned into a QueryException which would then trigger the reconnection and/or killing the worker.

See: https://github.com/laravel/framework/blob/9fb420cc29a7dd5de5051f09c523ffc3ea01b969/src/Illuminate/Database/Connection.php#L663

And then: https://github.com/laravel/framework/blob/9fb420cc29a7dd5de5051f09c523ffc3ea01b969/src/Illuminate/Database/Connection.php#L735

My understanding is that any Exception should be caught and then re-thrown as a QueryException, which would then be properly caught by the framework and then reconnected to the database.

This is an occasional error so it's difficult to reproduce; I've tried to manually throw a similar error but it is caught properly and handled properly.

Any general guidance on why this error might be different in production and ideas on how I can isolate the error would be appreciated.

0 likes
7 replies
KeithBrink's avatar

Thanks for your reply. I've researched MySQL connection errors extensively, and there are a couple reasons they are not applicable to this case:

  1. The Laravel framework is specifically coded to reconnect when the MySQL connection is dropped. See my original post for links.

  2. The queue is a long-running process, and no matter how long I set my MySQL timeout, the queue will eventually be alive for longer than that. There should be a mechanism within the queue to handle these, and in fact, there is, but for whatever reason it is not being triggered occasionally.

JaydeepMor's avatar

@keithbrink, did you resolve this ?

I tried following code in AppServiceProvide.php but still not working!

public function boot() {
    Queue::failing(function(JobFailed $event) {
        $entityManager = new EntityManager();
        $entityManager->getConnection()->close()
    });
    Queue::after(function(JobProcessed $event) {
        $entityManager = new EntityManager();
        $entityManager->getConnection()->close()
    });
}

Please or to participate in this conversation.