Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for MySQL By James Joyner IV · · 9 min read

MySQL Error Guide: 'ERROR 2006 (HY000)' MySQL Server Has Gone Away

Fix MySQL ERROR 2006 server has gone away: diagnose wait_timeout drops, oversized packets, a crashed or OOM-killed server, and stale pooled connections.

  • #mysql
  • #troubleshooting
  • #errors
  • #connectivity

Overview

ERROR 2006 (HY000) is a client-side error meaning the connection to the server was lost mid-session: the client sent a query but the server had already closed the connection (or never received it intact).

ERROR 2006 (HY000): MySQL server has gone away

Despite the alarming name, the server is usually fine — it is the connection that died. The two dominant causes are an idle connection the server reaped after wait_timeout, and a single packet larger than max_allowed_packet that the server rejected by closing the link. A genuinely crashed or OOM-killed server is the third, less common case. A closely related error, ERROR 2013 (HY000): Lost connection to MySQL server during query, points to the same family of causes.

It appears mid-session: the first query after an idle period, or a large INSERT/LOAD DATA/blob write.

Symptoms

  • A query fails with server has gone away, often the first one after an idle gap.
  • Large inserts or blob writes fail reliably at a certain size.
  • Pooled connections throw 2006 after the app has been quiet.
  • The server itself is up and serving other clients.
mysql -u app -p -e "INSERT INTO docs(body) VALUES (REPEAT('x',64*1024*1024));"
ERROR 2006 (HY000): MySQL server has gone away

Common Root Causes

1. Idle connection reaped after wait_timeout

The server closes connections idle longer than wait_timeout. A pooled connection that sat unused then gets used yields 2006.

SHOW VARIABLES LIKE 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+

If the pool’s idle timeout exceeds wait_timeout, the server drops the connection first and the next query fails.

2. Packet larger than max_allowed_packet

A single query/result exceeding max_allowed_packet makes the server abort the connection.

SHOW VARIABLES LIKE 'max_allowed_packet';
+--------------------+----------+
| Variable_name      | Value    |
+--------------------+----------+
| max_allowed_packet | 16777216 |
+--------------------+----------+
ERROR 2006 (HY000): MySQL server has gone away

A 64MB blob against a 16MB (16777216) limit reproducibly triggers 2006. The fix is raising the limit on both server and client.

3. The server crashed or was restarted

If mysqld restarted (crash, OOM, maintenance), every existing connection is severed.

journalctl -u mysql --no-pager | tail -8
[System] [MY-013172] Received SHUTDOWN from user root.
[System] [MY-010931] /usr/sbin/mysqld: ready for connections. version: '8.0.36'

A SHUTDOWN/startup pair shows a restart; uptime confirms:

SHOW STATUS LIKE 'Uptime';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Uptime        | 92    |
+---------------+-------+

A tiny Uptime (92s) right after a 2006 storm means the server just restarted.

4. The OOM killer terminated mysqld

Under memory pressure the kernel kills mysqld, which restarts and drops all connections.

dmesg -T | grep -i "killed process" | tail -3
[Tue Jun 23 08:41:55 2026] Out of memory: Killed process 1843 (mysqld) total-vm:9821044kB

An OOM kill of mysqld explains a sudden mass 2006 across all clients.

5. net_read_timeout / net_write_timeout on slow transfers

A slow network or a client that stalls mid-transfer can trip the read/write timeouts, closing the connection.

SHOW VARIABLES LIKE 'net_read_timeout';
SHOW VARIABLES LIKE 'net_write_timeout';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| net_read_timeout | 30    |
+------------------+-------+

A large result streamed to a slow consumer can exceed net_write_timeout and be cut off.

6. A long-running query killed by another session or timeout

A query that runs past max_execution_time or is KILLed appears to the client as the connection going away.

SHOW VARIABLES LIKE 'max_execution_time';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| max_execution_time | 0     |
+--------------------+-------+

(0 = unlimited; a non-zero value or an external KILL can surface as 2006/2013.)

Diagnostic Workflow

Step 1: Determine whether the server actually restarted

SHOW STATUS LIKE 'Uptime';

A small uptime right after the errors means a crash/restart — go to Step 4. A large uptime means the server stayed up and the connection died for another reason.

Step 2: Check if the error correlates with size or idleness

If it fails reliably on large statements, suspect max_allowed_packet. If it fails on the first query after idle time, suspect wait_timeout.

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

Step 3: Inspect server logs for shutdown/OOM

journalctl -u mysql --no-pager | tail -15
dmesg -T | grep -i "out of memory" | tail -3
grep -i "restart\|shutdown\|signal" /var/log/mysql/error.log | tail -10

This distinguishes a clean restart from an OOM kill or signal.

Step 4: Reproduce with a controlled large statement

mysql -u app -p -e "SELECT LENGTH(REPEAT('x', 20*1024*1024));"

If a 20MB statement fails but a small one works, the packet limit is the cause.

Step 5: Apply the fix and verify

-- Raise the packet limit (also set on the client / in my.cnf)
SET GLOBAL max_allowed_packet = 67108864;   -- 64MB
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
max_allowed_packet = 64M
wait_timeout = 600
[client]
max_allowed_packet = 64M

New connections pick up the runtime GLOBAL change; restart to persist. Then re-run the reproduction.

Example Root Cause Analysis

An import job that loads scanned-document blobs fails partway through, every run, with:

ERROR 2006 (HY000): MySQL server has gone away

The DBA checks server uptime — it is large and steady, so the server did not crash. The failures correlate with the biggest documents. Checking the limit:

SHOW VARIABLES LIKE 'max_allowed_packet';
+--------------------+----------+
| Variable_name      | Value    |
+--------------------+----------+
| max_allowed_packet | 16777216 |
+--------------------+----------+

The largest scans are ~40MB, well over the 16MB packet limit. Each oversized INSERT makes the server reject the packet and close the connection — surfacing as 2006.

Fix: raise max_allowed_packet on both server and client to 64MB and persist it in my.cnf:

SET GLOBAL max_allowed_packet = 67108864;

The import completes cleanly. (If the blobs were truly huge, chunking the writes or storing files outside the DB would be the better long-term design.)

Prevention Best Practices

  • Configure the connection pool’s idle timeout below the server’s wait_timeout, and enable a validation/keepalive query so stale connections are recycled before the server reaps them.
  • Set max_allowed_packet consistently on both server and client to cover your largest legitimate statement, and prefer chunked writes or external blob storage for very large objects.
  • Add automatic reconnect/retry around transient connection errors in the application so a single reaped connection does not surface as a user-facing failure.
  • Right-size MySQL memory (innodb_buffer_pool_size, per-connection buffers x max_connections) so the server is never a target for the OOM killer; alert on low free memory.
  • Monitor server Uptime and restart events so a crash or OOM is detected immediately rather than inferred from a flood of 2006s.
  • For quick triage of whether a 2006 storm is a restart vs. a packet/idle issue, the free incident assistant can correlate uptime and logs. More in MySQL guides.

Quick Command Reference

-- Did the server restart?
SHOW STATUS LIKE 'Uptime';

-- The two prime suspects
SHOW VARIABLES LIKE 'max_allowed_packet';
SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'net_read_timeout';
SHOW VARIABLES LIKE 'net_write_timeout';

-- Raise the packet limit (set on client + my.cnf too)
SET GLOBAL max_allowed_packet = 67108864;
# Server-side crash / OOM evidence
journalctl -u mysql --no-pager | tail -15
dmesg -T | grep -i "out of memory" | tail -3
grep -i "restart\|shutdown" /var/log/mysql/error.log | tail -10

# Reproduce with a large statement
mysql -u app -p -e "SELECT LENGTH(REPEAT('x', 20*1024*1024));"

Conclusion

ERROR 2006 (HY000) means the client’s connection to the server was lost mid-session. The usual root causes:

  1. An idle connection reaped by the server after wait_timeout (often a pool whose idle timeout is too high).
  2. A statement or result larger than max_allowed_packet, which the server rejects by closing the link.
  3. A server crash or clean restart that severed all connections.
  4. The OOM killer terminating mysqld under memory pressure.
  5. net_read_timeout / net_write_timeout tripping on slow transfers.
  6. A long query hitting max_execution_time or an external KILL.

Check Uptime first to rule a restart in or out, then correlate the failures with statement size (packet limit) or idleness (wait_timeout). Aligning pool timeouts, raising the packet limit on both sides, and adding reconnect logic resolve the vast majority of 2006 errors.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.