Incident Response

"MySQL server has gone away" (Error 2006): Causes and Fixes That Actually Work

Error 2006 is a symptom, not a diagnosis. The connection was closed by the server, the network, a proxy or your own code, and each of those needs a different fix. Here is how to tell which one you have before you start raising timeouts.

· 15 min read · AG Data Team

"MySQL server has gone away" is client error 2006. It means the client tried to use a connection that no longer works. The error tells you nothing about why the connection is gone. The MySQL manual lists more than ten possible causes, from an idle timeout to a server crash, and the fix for one is useless for another. So the first job is not to change a setting but to find out who closed the connection.

2006, 2013 and 4031: three faces of the same problem

ERROR 2006 (HY000): MySQL server has gone away
ERROR 2013 (HY000): Lost connection to MySQL server during query
ERROR 4031 (HY000): The client was disconnected by the server because of inactivity.
                    See wait_timeout and interactive_timeout for configuring this behavior.

If you see 4031, you can skip most of this article: the connection sat idle too long. If you see 2006 or 2013, keep reading.

Step 1: collect four facts

Before changing anything, run this on the server:

SHOW GLOBAL VARIABLES WHERE Variable_name IN
  ('wait_timeout', 'interactive_timeout', 'max_allowed_packet',
   'net_read_timeout', 'net_write_timeout', 'connect_timeout');

SHOW GLOBAL STATUS WHERE Variable_name IN
  ('Uptime', 'Aborted_clients', 'Aborted_connects');

Then answer four questions:

  1. Did the server restart? Compare Uptime with the time of the errors. The manual suggests exactly this check: if the connection broke because mysqld crashed and restarted, the error is the least of your problems and the crash is what to investigate. Check the error log.
  2. How long had the connection been idle? If the failing request is the first one after a quiet period (overnight jobs, a worker that wakes up once an hour, a connection pool after a weekend) and the gap is longer than the session's wait_timeout, you have found it.
  3. How big was the request? A huge INSERT, a large BLOB or a long generated query points at max_allowed_packet.
  4. Did someone or something kill the session? A KILL from a DBA, a monitoring script that kills long queries, or a failover tool all look identical from the client side.

The manual also suggests starting mysqld with log_error_verbosity set to 3 to log some of the disconnection messages in the error log, which helps when the client side tells you nothing.

Cause 1: the connection was idle longer than wait_timeout

This is the cause the manual calls the most common one. By default the server closes a connection after eight hours without activity: wait_timeout and interactive_timeout both default to 28800 seconds.

There is a trap in how these two interact. Per the server variables reference, when a session starts, its wait_timeout is initialized from the global wait_timeout or from the global interactive_timeout, depending on whether the client connected with the CLIENT_INTERACTIVE option. Changing only one of the two globals therefore may not affect the connections you care about. Check what the session really got:

-- what THIS session actually got (may differ from the global value)
SELECT @@SESSION.wait_timeout, @@GLOBAL.wait_timeout, @@GLOBAL.interactive_timeout;

Teams that lowered wait_timeout to clean up idle connections, which our article on "Too many connections" suggests considering, sometimes forget the application side. If the connection pool keeps connections longer than the server does, the pool will eventually hand out a dead one.

The fix belongs in the application, not in a bigger timeout:

Do not forget what sits between the application and MySQL. Load balancers, proxies, NAT gateways and firewalls can have their own idle timeouts and silently drop TCP connections that MySQL still considers open. If wait_timeout is eight hours but connections die after a few minutes of silence, look at the network path.

Cause 2: the packet was too large

From the "Packet Too Large" page: when a MySQL client or the mysqld server receives a packet bigger than max_allowed_packet bytes, it issues an ER_NET_PACKET_TOO_LARGE error (1153, "Got a packet bigger than 'max_allowed_packet' bytes") and closes the connection. Some clients only show you the closed connection, which is why this often appears as 2006 or 2013.

Key numbers from the manual:

Both sides have their own variable, so a large import may need the setting raised on the client as well as the server:

[mysqld]
max_allowed_packet = 128M

# and on the client side, for example:
# mysql --max_allowed_packet=128M

Before raising it, check whether you need to. The manual points out that an INSERT or REPLACE with a great many rows is sent as a single request, and you can often avoid the error by sending fewer rows per statement. Smaller batches are usually easier on the server, on replication and on your retry logic than one giant statement.

Cause 3: the query or result took too long on the wire

The lost connection page covers the 2013 variant. If the message includes "during query", the manual says network trouble is the likely cause. It also describes a case where millions of rows are being sent and suggests increasing net_read_timeout from its default of 30 seconds to 60 seconds or longer. Its sibling net_write_timeout defaults to 60 seconds and controls how long the server waits when writing to the client. A client that reads a huge result set slowly, for example processing each row before fetching the next, can run into it.

Client-side timeouts matter too. The manual mentions the C API read and write timeout options; most drivers have equivalents. If the driver gives up after 30 seconds on a query that takes 40, the result looks like a lost connection even though the server is fine.

For errors at connect time, the manual points to connect_timeout (default 10 seconds) and to the Aborted_connects status counter, which increases by one for each initial connection attempt the server aborts. "reading authorization packet" in the message is a hint in that direction.

Cause 4: the session was killed or the server went down

The manual lists a KILL statement or mysqladmin kill as a cause. In practice this includes tools that kill long-running queries automatically, which is worth checking if errors cluster around heavy reports. Our lock wait timeout guide shows how to find blocking sessions, which are a common reason someone reaches for KILL in the first place.

A server crash, an OOM kill or a failover to a replica also ends every connection. If Uptime is short, start with the error log and the system log, not the client.

Cause 5: bugs in the application's connection handling

Two causes from the manual come straight from application code:

Be careful with automatic reconnect. The C API documentation says auto-reconnect is disabled by default and the feature is deprecated. When a reconnect does happen, the server-side session state is reset and the application is not notified: active transactions are rolled back, table locks and GET_LOCK() locks are released, temporary tables are dropped, session variables and user variables are lost, and LAST_INSERT_ID() resets to 0. Code that silently reconnects in the middle of a transaction can carry on as if half its work was not just thrown away. Reconnect, then restart the whole unit of work.

Use Aborted_clients as an early warning

The communication errors page explains that when a client connects successfully but later disconnects improperly or is terminated, the server increments Aborted_clients and logs an "Aborted connection" message. Causes include a client exiting without closing the connection, a client sleeping longer than wait_timeout or interactive_timeout, a client ending in the middle of a data transfer, a too-small max_allowed_packet, and faulty network hardware. Graph the counter. A steady trickle is normal for many applications; a sudden increase after a deploy or a network change tells you where to look before users start reporting errors.

Key takeaways

MySQL Connections Timeouts Troubleshooting
Work with us

Connections dropping in production?

We trace dropped MySQL connections to the server, the network or the application and fix the cause instead of just raising timeouts.

Get in touch More from the blog