MySQL Server Has Gone Away Not Working: causes and solutions

Quick Answer

The “MySQL server has gone away” error (error code 2006) occurs when your PHP script or application loses its database connection mid-operation. In 2026, the most common culprits are oversized packets exceeding the max_allowed_packet limit, idle connection timeouts, and overloaded servers hitting resource caps. Fix it by tuning MySQL configuration, optimizing query sizes, and implementing proper reconnection logic.

Why This Matters

MySQL powers over 45% of all websites using relational databases, according to W3Techs’ latest survey. That number matters because this error doesn’t just annoy developers—it kills user sessions, corrupts data imports, and, in e-commerce, directly translates to abandoned carts. I watched a client lose 200 orders during a bulk product import because their import script ran straight into a timeout wall. The error is deceptively simple. The root causes span client config, server config, network issues, and application logic—often simultaneously.

What Triggers the “MySQL Server Has Gone Away” Error?

Three categories of triggers account for roughly 90% of cases I encounter. First, packet size violations. MySQL has a hard limit called max_allowed_packet (default: 4MB in most builds). When you try to send or receive anything larger—think BLOB fields, long TEXT columns, or poorly constructed JSON payloads—the server terminates the connection. Second, idle timeouts. The MySQL server closes connections that sit idle past the wait_timeout threshold (default: 28800 seconds, or 8 hours—but PHP scripts that hold connections for long-running tasks often hit shorter Apache or Nginx timeouts first). Third, server crashes or restarts. If MySQL restarts mid-query, clients get this error instead of a graceful reconnection.

Less common triggers include binary log corruption, insufficient disk space on the server, and hitting connection limits (max_connections). DNS failures can also produce this error on hosts with unstable name resolution.

How Do You Diagnose the Exact Cause?

Check the MySQL error log first. It’s usually at /var/log/mysql/error.log on Ubuntu/Debian or /var/log/mysqld.log on CentOS/RHEL. Look for entries surrounding the timestamp when your script failed. Common log messages include “Error reading packet from server,” “Got timeout reading communication packets,” and “Lost connection to MySQL server during query.”

Next, run this diagnostic query while the issue is fresh:

SHOW GLOBAL STATUS LIKE 'Aborted_connects';
SHOW GLOBAL STATUS LIKE 'Aborted_connects';

If that number increments rapidly during your error window, the server is actively rejecting connections. Then check current connection counts:

SHOW STATUS LIKE 'Threads_connected';
SHOW VARIABLES LIKE 'max_connections';

If Threads_connected approaches max_connections, you have a resource starvation problem.

Which MySQL Configuration Changes Fix It?

For packet size errors, edit your my.cnf (or my.ini on Windows):

[mysqld]
max_allowed_packet = 64M
net_read_timeout = 60
net_write_timeout = 60

Set max_allowed_packet to at least 64MB if you’re handling large imports or media uploads. The net_read_timeout and net_write_timeout values give MySQL more patience during slow transfers.

For timeout issues, add:

[mysqld]
wait_timeout = 600
interactive_timeout = 600
connect_timeout = 10

Reduce wait_timeout only if your application handles reconnection properly. Shorter timeouts free server resources faster but break poorly written scripts that expect persistent connections.

Restart MySQL after editing: sudo systemctl restart mysql. Verify changes with:

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

How Does Your Application Code Contribute?

Even perfect server config can’t save a script that doesn’t handle disconnections. The most common PHP mistake is running long operations (cron jobs, data syncs) without checking connection health mid-process. Here’s a minimal reconnection wrapper pattern I use:

function getDbConnection() {
    static $pdo = null;
    if ($pdo === null) {
        try {
            $pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            error_log('DB connection failed: ' . $e->getMessage());
            throw $e;
        }
    }
    return $pdo;
}

function runQuerySafely($sql) {
    $pdo = getDbConnection();
    try {
        return $pdo->query($sql);
    } catch (PDOException $e) {
        if (strpos($e->getMessage(), 'server has gone away') !== false) {
            $pdo = null; // force reconnect
            return runQuerySafely($sql);
        }
        throw $e;
    }
}

WordPress users should consider the WP_MEMORY_LIMIT increase and installing a database optimizer plugin that flushes stale connections. For Laravel, set 'persistent' => false in config/database.php to avoid connection reuse issues.

What About phpMyAdmin and Hosting Panel Users?

If you’re seeing this error while importing via phpMyAdmin, the import size limit is likely your bottleneck. phpMyAdmin defaults to a 50MB upload cap, but MySQL’s max_allowed_packet often defaults to 4MB—meaning imports exceeding 4MB fail silently or with the “server has gone away” message.

Fix it in two places. First, increase phpMyAdmin’s limit in php.ini:

upload_max_filesize = 128M
post_max_size = 128M
memory_limit = 256M

Second, increase MySQL’s packet size as shown above. Then restart Apache: sudo systemctl restart apache2.

On cPanel servers, you can adjust max_allowed_packet via the “MySQL Configuration” interface in WHM, but many shared hosts cap this value at 32MB for resource fairness. If you’re on shared hosting and hitting this error regularly, it’s a signal to migrate to VPS or dedicated infrastructure.

Related Guides on abdulabror.com

FAQ

Q: Can a firewall cause the “MySQL server has gone away” error?

Yes. Stateful firewalls that track idle connections can drop them after extended silence. If your MySQL server sits behind a cloud provider’s firewall (AWS Security Groups, Google Cloud Firewall), ensure the idle timeout settings match or exceed MySQL’s wait_timeout. Connection tracking drops are silent—your app sees a generic “server has gone away” without any server-side log entry.

Q: Does increasing max_allowed_packet affect memory usage?

It does. MySQL allocates max_allowed_packet per connection, so a 256MB setting on a server with 100 active connections could use up to 25GB in worst-case scenarios. Set it high enough for your needs (64MB handles most bulk operations) but not unlimited. The official MySQL documentation recommends monitoring memory with SHOW GLOBAL STATUS LIKE 'Max_used_connections' after tuning.

Q: Why does the error happen during INSERT but not SELECT queries?

SELECT queries return data; INSERT queries send it. Large INSERT statements (especially batched INSERTs with multiple rows or long TEXT/BLOB values) push your payload size toward the max_allowed_packet limit. SELECT queries rarely approach that limit unless you’re fetching enormous LONGTEXT columns. If you’re seeing the error only on writes, examine the payload size of your INSERT statements.

Q: Is the error different from “Lost connection to MySQL server during query”?

Both are connection-loss errors, but error 2013 (“Lost connection during query”) typically means the query was running and the server died or the connection broke mid-execution. Error 2006 (“Server has gone away”) usually means the connection was already dead when your client tried to use it. The diagnostic approach overlaps significantly, but 2013 more often points to query complexity or server overload, while 2006 points to configuration or idle timeouts.

Q: How do I prevent the error during automated cron jobs?

Cron jobs that run infrequently (hourly or daily) are prime candidates for timeout issues because the database connection sits idle for long stretches. Configure your cron script to establish a fresh connection at startup and set wait_timeout to a value longer than the longest gap between runs, or use mysqli_ping() before each query to detect and recover from dead connections. For PHP: if (!$mysqli->ping()) { $mysqli = new mysqli(...); }



Leave A Comment

Need help with WordPress or hosting?

Based in Bali, Indonesia

Providing technical hosting support and WordPress services to clients worldwide. Remote-friendly, reliable, and always focused on practical solutions.

Samping work with me