MySQL Error 2013 occurs when the connection between your client and database server is unexpectedly terminated while executing a query. This happens due to timeouts, oversized packets, network instability, or server overload. Solutions include increasing timeout values, optimizing slow queries, raising max_allowed_packet, and ensuring stable network connectivity.
MySQL Error 2013 indicates that an established connection was lost during query execution. The server or client terminates the connection before the query completes, usually because the query takes too long, the server becomes unresponsive, network issues occur, or data packets exceed the maximum allowed size. This is a connectivity error, not a syntax or logic error—the query itself may be valid, but the connection can't sustain it.
The default net_read_timeout is 30 seconds. For long queries or slow networks, increase this value:
-- Check current setting:
SHOW VARIABLES LIKE 'net_read_timeout';
-- Set temporarily (until server restart):
SET GLOBAL net_read_timeout = 60;
-- Set permanently in my.cnf or my.ini:
[mysqld]
net_read_timeout = 60Restart MySQL for changes to take effect:
# Linux:
sudo systemctl restart mysql
# macOS:
brew services restart [email protected]Increase further (120-300 seconds) if queries still timeout.
These settings control how long a connection can remain idle:
-- Check current values:
SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'interactive_timeout';
-- Set temporarily:
SET GLOBAL wait_timeout = 600;
SET GLOBAL interactive_timeout = 600;
-- Set permanently in my.cnf:
[mysqld]
wait_timeout = 600
interactive_timeout = 600The default is 28800 seconds (8 hours), but can be reduced by your hosting provider. Increase to at least 600-3600 seconds.
If you're transferring large BLOB, TEXT, or JSON data, increase this limit:
-- Check current setting:
SHOW VARIABLES LIKE 'max_allowed_packet';
-- Set temporarily:
SET GLOBAL max_allowed_packet = 64M;
-- Set permanently in my.cnf:
[mysqld]
max_allowed_packet = 64M
-- Also set on client side (mysqldump, mysql CLI):
[mysqldump]
max_allowed_packet = 64M
[mysql]
max_allowed_packet = 64MDefault is 4MB. Increase to 16MB, 32MB, or 64MB depending on your data size. Note: This requires a server restart.
Long-running queries are the primary cause of ERROR 2013. Identify and optimize them:
-- Enable slow query log to find culprits:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 5; -- Log queries taking >5 seconds
-- Check the log:
-- Location: /var/log/mysql/slow.log (Linux) or MySQL datadirOptimization tips:
- Add indexes to WHERE, JOIN, and ORDER BY columns
- Use EXPLAIN to analyze query execution plans
- Reduce result set size with LIMIT
- Break complex queries into smaller operations
- Avoid SELECT * and fetch only needed columns
- Use materialized views or caching for complex aggregations
Example optimization:
-- SLOW (without index):
SELECT * FROM orders WHERE customer_id = 123;
-- FAST (with index):
CREATE INDEX idx_customer_id ON orders(customer_id);
SELECT id, amount FROM orders WHERE customer_id = 123;Server overload (CPU, memory, disk) can cause connections to drop:
# Check system resources:
top
free -h
df -h
# Check MySQL process:
ps aux | grep mysqldMonitor MySQL:
-- Show active processes:
SHOW PROCESSLIST;
-- Kill long-running queries (dangerous, use carefully):
KILL QUERY {thread_id};
-- Check server status:
SHOW STATUS LIKE 'Threads%';
SHOW STATUS LIKE 'Questions';If consistently out of resources:
- Upgrade server hardware (RAM, CPU, storage)
- Add read replicas to distribute load
- Implement connection pooling (e.g., ProxySQL, pgBouncer)
- Archive old data to reduce table size
Implement automatic reconnection in your application code:
JavaScript/Node.js:
const mysql = require('mysql2/promise');
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'mydb',
waitForConnections: true,
connectionLimit: 10,
enableTimeout: true,
queueLimit: 0
});
// Retry logic:
async function queryWithRetry(sql, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await connection.query(sql);
} catch (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST' && i < maxRetries - 1) {
console.log('Connection lost, retrying...');
await new Promise(r => setTimeout(r, 1000));
} else {
throw err;
}
}
}
}Python:
import mysql.connector
from time import sleep
def query_with_retry(sql, max_retries=3):
for i in range(max_retries):
try:
connection = mysql.connector.connect(
host='localhost',
user='root',
password='password',
database='mydb',
connection_timeout=30
)
cursor = connection.cursor()
cursor.execute(sql)
return cursor.fetchall()
except mysql.connector.Error as err:
if err.errno in [2006, 2013] and i < max_retries - 1:
print(f"Connection lost, retrying... ({i+1}/{max_retries})")
sleep(1)
else:
raiseIf connecting over a network:
# Test connectivity:
ping mysql.example.com
# Check for packet loss:
ping -c 100 mysql.example.com
# Monitor network with MTR:
mtr mysql.example.comIf double-NAT or firewall issues exist:
- Use VPN or SSH tunnel
- Configure firewall to allow persistent connections
- Set TCP keepalive on the connection:
# Linux socket options (in application):
tcp_keepalives_idle = 600
tcp_keepalives_interval = 60
tcp_keepalives_count = 5MySQL connection with SSL/TLS (more stable):
-- Create user with SSL requirement:
CREATE USER 'user'@'host' IDENTIFIED BY 'password' REQUIRE SSL;ERROR 2013 is often a symptom of deeper issues: chronic underprovisioning manifests as timeouts, inefficient queries overwhelm the server, and network instability is common in cloud environments. The best fix is architectural: add connection pooling (ProxySQL, MySQL Router), implement query timeouts at the application level, use read replicas to distribute load, and monitor with tools like Percona Monitoring & Management (PMM). If using managed MySQL (AWS RDS, Google Cloud SQL, Azure Database), check the provider's timeout limits—they may override your my.cnf settings. For Percona XtraDB Cluster or Galera, ERROR 2013 may indicate replication lag; check SHOW STATUS LIKE 'wsrep%'; in those cases.
EE_WRITE (3): Error writing file
How to fix "EE_WRITE (3): Error writing file" in MySQL
CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters
How to fix "CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters" in MySQL
CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed
How to fix "CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed" in MySQL
ERROR 1146: Table 'database.table' doesn't exist
How to fix "ERROR 1146: Table doesn't exist" in MySQL
ERROR 1040: Too many connections
How to fix "ERROR 1040: Too many connections" in MySQL