MySQL Error Guide: 'Lost connection to MySQL server during query' — Fix Dropped Queries
Fix MySQL error 2013 'Lost connection during query': timeouts, oversized packets, OOM kills, network drops, and long-running statements that break mid-execution.
- #mysql
- #database
- #troubleshooting
- #errors
Stuck on this MySQL error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
MySQL error 2013 is a client-side error meaning the connection dropped while a query was in flight — the client sent a statement but never received a complete reply:
ERROR 2013 (HY000): Lost connection to MySQL server during query
It is closely related to but distinct from error 2006 (“MySQL server has gone away”). 2006 usually means the connection was already dead when the client tried to use it (idle timeout, server restart); 2013 means the break happened during an active query — a long statement was killed, a packet was too big, the network hiccuped, or the server process died mid-execution.
Symptoms
- A long-running
SELECT,ALTER TABLE, backup, or bulkINSERTdies partway through with 2013. - The failure is time-correlated — it always breaks around the same elapsed seconds (a timeout).
- Import tools (
mysql < dump.sql,mysqldump, loaders) fail on a specific large statement. - Application logs show 2013 spikes that line up with a server restart or an OOM event.
Common Root Causes
- Query exceeds a read/write timeout —
net_read_timeout/net_write_timeout, or a client-sideMAX_EXECUTION_TIME/ driver socket timeout, fires and the socket is torn down mid-query. - Packet too large — a single row or result exceeds
max_allowed_packet; the server closes the connection rather than returning it (often reported as 2013 during large imports). - Server crash or OOM kill — the
mysqldprocess was killed by the OOM killer or crashed during the query, dropping every in-flight connection. - Network interruption — a firewall/NAT idle-flow timeout, load balancer, or flaky link drops the TCP connection during a slow query.
- A killed thread — someone (or an automated killer) ran
KILLon the query’s connection. - Statement genuinely too slow — a missing index turns a query into a multi-minute scan that outlives some timeout in the path.
Diagnostic Workflow
First separate the two failure shapes — timeout vs crash. Check whether the server actually restarted:
SHOW GLOBAL STATUS LIKE 'Uptime'; -- low value = recent restart/crash
SHOW GLOBAL STATUS LIKE 'Aborted_clients'; -- rising = connections dropped mid-use
Inspect the timeouts and packet limit that most often cause 2013:
SHOW VARIABLES LIKE 'max_allowed_packet';
SHOW VARIABLES LIKE 'net_read_timeout';
SHOW VARIABLES LIKE 'net_write_timeout';
SHOW VARIABLES LIKE 'wait_timeout';
While reproducing, watch the running query and how long it lives:
SELECT id, user, host, time, state, LEFT(info, 120) AS query
FROM information_schema.PROCESSLIST
WHERE command <> 'Sleep' ORDER BY time DESC;
Confirm whether the query itself is pathological (full scan) so you fix the cause, not just the timeout:
EXPLAIN SELECT ... ; -- look for type: ALL and large rows examined
Correlate with the server error log and the OS — an OOM kill only shows up outside MySQL:
# server side
sudo tail -n 100 /var/log/mysql/error.log # MySQL
sudo journalctl -u mariadb --since '15 min ago' # MariaDB
sudo dmesg | grep -i 'out of memory\|killed process mysqld'
Example Root Cause Analysis
A nightly job importing a 6 GB dump failed reproducibly with 2013 on the same large INSERT:
ERROR 2013 (HY000): Lost connection to MySQL server during query
Uptime was high and the error log showed no crash, ruling out an OOM kill. The failing statement was a single multi-row INSERT for a table with a large LONGBLOB. Checking the limit:
SHOW VARIABLES LIKE 'max_allowed_packet';
-- max_allowed_packet | 16777216 (16 MB)
One row’s blob exceeded 16 MB, so the server rejected the packet and dropped the connection mid-statement, surfacing as 2013. Raising the limit on both server and client resolved it:
SET GLOBAL max_allowed_packet = 268435456; -- 256 MB, session-safe for the import
mysql --max-allowed-packet=256M app < dump.sql
Had the cause instead been dmesg showing killed process mysqld, the fix would have been memory-side — lowering innodb_buffer_pool_size or per-connection buffers so the host stops OOM-killing the server.
Prevention Best Practices
- Set
max_allowed_packetconsistently on both the server (my.cnf) and the client/driver; large blobs and big imports need matching values. - Raise
net_read_timeout/net_write_timeoutfor legitimately long operations, but fix the underlying slow query (add the missing index) rather than only extending timeouts. - Size
innodb_buffer_pool_sizeand per-connection buffers so total memory stays under host RAM; monitor for OOM so the server never gets killed mid-query. - Configure firewall/NAT/load-balancer idle timeouts to exceed your longest legitimate query, or use TCP keepalives, so long statements are not dropped by the network.
- For big imports, use
--max-allowed-packeton the client and chunk very large batches.
Quick Command Reference
SHOW GLOBAL STATUS LIKE 'Uptime'; -- did the server restart/crash?
SHOW GLOBAL STATUS LIKE 'Aborted_clients'; -- connections dropped mid-use
SHOW VARIABLES LIKE 'max_allowed_packet';
SHOW VARIABLES LIKE 'net_read_timeout';
SELECT id,time,state,LEFT(info,120) FROM information_schema.PROCESSLIST WHERE command<>'Sleep';
SET GLOBAL max_allowed_packet = 268435456; -- raise for large-row imports
sudo tail -n 100 /var/log/mysql/error.log # MySQL error log
sudo journalctl -u mariadb --since '15 min ago' # MariaDB
sudo dmesg | grep -i 'killed process mysqld' # OOM kill evidence
Conclusion
Error 2013 means a connection died while a query ran, so the diagnosis is a fork: was the query killed by a timeout or packet limit, or did the server itself go down? Check Uptime and the error log / dmesg first to rule out a crash or OOM kill, then inspect max_allowed_packet and the net_* timeouts, and finally EXPLAIN the statement so you fix a pathological scan rather than papering over it with a larger timeout.
The behavior is effectively identical on MySQL and MariaDB; the main operational difference is where the server logs live and the service name for journalctl (mysql vs mariadb). In both, max_allowed_packet must be set on server and client, and a genuine OOM kill is only visible from the OS, never from inside MySQL.
Fixed it? Get 500 MySQL & DevOps AI prompts — free
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.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
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.