MySQL

How to Fix "MySQL Server Has Gone Away" Error During Query Execution

4 min read by DebuggedIt

Quick answer

A query that was working fine suddenly fails mid-execution with MySQL claiming the server disappeared, even though MySQL is clearly still running and other...

A query that was working fine suddenly fails mid-execution with MySQL claiming the server disappeared, even though MySQL is clearly still running and other connections work normally. This error means the specific connection your application was using got closed β€” usually due to a timeout or a packet size limit β€” not that the database server actually went down.

The Problem

A long-running script or an app that's been idle for a while suddenly can't execute a query:

$ mysql -u app_user -p mydb < import.sql
ERROR 2006 (HY000) at line 412: MySQL server has gone away

In application code, it often surfaces as a driver-level exception instead:

SQLSTATE[HY000]: General error: 2006 MySQL server has gone away

It's especially common with large INSERT statements or bulk imports:

ERROR 2006 (HY000): MySQL server has gone away
Query: INSERT INTO logs (message) VALUES ('...') -- (18 MB of data)

Why It Happens

This error means the TCP connection between your client and MySQL was closed before the query finished, for one of a small set of well-known reasons:

  • Connection idle timeout β€” MySQL's wait_timeout (default 28800 seconds / 8 hours, but often much lower in managed cloud environments) closes connections that sit idle too long. A connection pool holding onto a stale connection and reusing it after this timeout hits the error immediately.
  • Query or packet too large β€” MySQL's max_allowed_packet setting caps how big a single query or result can be. A large INSERT, a big BLOB, or a bulk import exceeding this limit gets the connection killed rather than truncated.
  • The MySQL server actually restarted or crashed mid-query, which is rarer but worth ruling out via server logs.
  • A network device (firewall, load balancer, proxy) between client and server has its own idle connection timeout shorter than MySQL's, silently dropping the TCP connection without either side immediately noticing.
Idle connection reused after timeout connection opened idle 9h > wait_timeout server closes it app reuses stale conn -> ERROR 2006 Fix: pool validates or pings before reuse

The Fix

Check the current timeout and packet size settings first:

SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'max_allowed_packet';

For long-running batch operations, increase max_allowed_packet for the session or globally:

SET GLOBAL max_allowed_packet = 64*1024*1024; -- 64 MB

Set it in my.cnf for a persistent change that survives restarts:

[mysqld]
max_allowed_packet = 64M

If idle connections are the cause, increase wait_timeout for long-lived but sparsely-used connections:

SET GLOBAL wait_timeout = 600;
SET GLOBAL interactive_timeout = 600;

The more robust fix, especially for application connection pools, is making sure the pool validates connections before handing them out rather than assuming they're still alive. Most connection pool libraries support a "test on borrow" or ping-before-use setting β€” enable it so a stale connection gets silently replaced instead of causing a query failure:

# Example: PHP PDO with a persistent connection pool
$pdo = new PDO($dsn, $user, $pass, [
    PDO::ATTR_PERSISTENT => true,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET SESSION wait_timeout=600"
]);

For bulk imports specifically, splitting one enormous statement into smaller batched inserts avoids hitting max_allowed_packet at all, and is generally more reliable than raising the limit indefinitely:

# Instead of one massive INSERT with thousands of rows,
# batch in chunks of a few hundred rows at a time
mysqldump --max_allowed_packet=64M --extended-insert=FALSE mydb > dump.sql

Still Not Working?

If none of the timeout or packet settings explain it, check whether a firewall, load balancer, or cloud NAT gateway between your application and MySQL has its own idle connection timeout shorter than MySQL's β€” this is common with managed database services behind a proxy layer, where the proxy silently drops connections MySQL itself would have kept alive:

SHOW GLOBAL STATUS LIKE 'Aborted_clients';

A steadily climbing Aborted_clients counter, especially correlating with connections that were idle for a specific, consistent duration, points at an intermediate network device enforcing its own timeout rather than MySQL's configuration being the actual limiting factor.