SYSTEMS OPERATIONAL
Troubleshooting

MySQL Server Has Gone Away: Causes and How to Fix It

Getwebup 6 min read

You're mid-import, or your WordPress site suddenly throws a database error, and the log says: MySQL server has gone away. Nothing looks obviously broken - the site loads fine a second later. That's the confusing part. This error isn't really about MySQL crashing (though it can be); most of the time it's about a connection that sat idle too long, or a query that was simply too big for MySQL to accept.

What This Error Actually Means

"MySQL server has gone away" means the PHP process (or mysql client) had an open connection to MySQL, and by the time it tried to use that connection, MySQL had already closed it. The client didn't get a graceful error - it just found the socket dead. There are really only four reasons this happens:

  • The connection sat idle longer than MySQL's wait_timeout, so MySQL closed it server-side.
  • The query (or a piece of data in it, like a base64 image or a large post body) exceeded max_allowed_packet.
  • MySQL itself restarted, crashed, or got killed by the OOM killer mid-request.
  • A network blip or firewall/proxy timeout dropped the TCP connection (common with remote MySQL over the internet).

Cause 1: wait_timeout Killed an Idle Connection

This is the most common cause on shared hosting and cPanel VPS setups. MySQL closes any connection that's been idle longer than wait_timeout (default is 28800 seconds / 8 hours on most installs, but cPanel/CloudLinux tunes it much lower - often 60-300 seconds - to stop idle connections piling up under CloudLinux's LVE limits).

You'll hit this when:

  • A long-running PHP script opens a DB connection, does something slow (like calling an external API), then tries to write to the database again.
  • A cron job or WP-Cron task holds a connection open between queries.
  • Persistent connections (mysqli with the p: prefix, or old mysql_pconnect) get reused after sitting idle across requests.

Check the current value in WHM > MySQL/MariaDB Configuration, or via SSH:

mysql -u root -p -e "SHOW VARIABLES LIKE 'wait_timeout';"

Fix It

Don't just crank wait_timeout up - fix the code path holding the connection open where you can, and raise the timeout modestly as a safety net.

# In /etc/my.cnf (or /etc/mysql/mariadb.conf.d/50-server.cnf)
[mysqld]
wait_timeout = 300
interactive_timeout = 300

# Restart after editing
systemctl restart mysql   # or mariadb, or via WHM MySQL Configuration

On shared cPanel hosting you usually can't touch my.cnf directly - use WHM > MySQL/MariaDB Configuration > Config Editor, or ask support to raise it for your account. In WordPress specifically, avoid holding a DB connection open across a slow wp_remote_get() call - do the external call first, then touch the database.

Cause 2: max_allowed_packet Is Too Small

This one shows up as "gone away" the moment you try to insert or update something large - a big serialized options row, a base64-encoded image pasted into a post, or a bulk INSERT during a database import. MySQL rejects the packet outright and drops the connection instead of returning a clean "too large" error, which is exactly what makes this cause confusing.

Check the current limit:

mysql -u root -p -e "SHOW VARIABLES LIKE 'max_allowed_packet';"

Default is often 4 MB or 16 MB depending on the MySQL/MariaDB version. If you're importing a large .sql dump via phpMyAdmin or SSH and it fails partway through with this error, this is almost always the cause.

Fix It

# /etc/my.cnf
[mysqld]
max_allowed_packet = 256M

[mysqldump]
max_allowed_packet = 256M

systemctl restart mysql

For a one-off import over SSH without editing the config file:

mysql --max_allowed_packet=256M -u dbuser -p dbname < dump.sql

On managed cPanel hosting, raise it through WHM > MySQL/MariaDB Configuration, or import via SSH with the flag above instead of phpMyAdmin, which has its own upload and memory ceilings on top of this one.

Cause 3: MySQL Actually Crashed or Restarted

Sometimes the server really did go away. On a VPS with limited RAM, MySQL is a common target for the Linux OOM killer when memory runs out - it gets killed to free up memory, then usually auto-restarts via systemd, but any connection open at that moment breaks with this exact error.

Check for this specifically:

# OOM kill evidence
dmesg | grep -i "killed process" | grep -i mysql
grep -i "oom" /var/log/syslog

# MySQL's own error log - look for a recent restart
tail -100 /var/log/mysql/error.log
# or on cPanel:
tail -100 /var/lib/mysql/$(hostname).err

If you see MySQL restarting on its own repeatedly, it's not a config tweak you need - it's more RAM, less concurrent load, or a lower innodb_buffer_pool_size. See our guide on diagnosing OOM kills and adding swap if this is happening on a VPS.

Cause 4: Remote MySQL Over an Unstable Network

If your app connects to a MySQL server on a different machine (a separate database server, or an app hosted elsewhere connecting back to cPanel's Remote MySQL feature), a firewall, load balancer, or NAT gateway between the two can silently drop idle TCP connections well before MySQL's own wait_timeout kicks in. The app has no idea the socket died until it tries to use it.

Fix It

  • Enable TCP keepalive on the client side so idle connections send periodic probes instead of going silent.
  • Lower your app's own connection-pool idle timeout below whatever the network path enforces (test both 60s and 300s).
  • Wrap DB calls in reconnect logic - most drivers (PDO, mysqli, ORMs like Laravel's Eloquent) support automatic reconnect-on-lost-connection; turn it on rather than hand-rolling retries.

Quick Reference Table

SymptomLikely CauseFix
Fails after the site sits idle, then works on reloadwait_timeoutRaise wait_timeout, avoid holding connections open across slow calls
Fails only on large imports or big post contentmax_allowed_packetRaise max_allowed_packet in my.cnf and mysqldump section
Fails randomly, MySQL error log shows a restartOOM kill / crashAdd RAM/swap, lower innodb_buffer_pool_size, check for OOM kills
Only happens on remote/cross-server DB connectionsNetwork/firewall idle timeoutTCP keepalive, shorter pool idle timeout, reconnect logic

Prevention

  • Enable auto-reconnect in your database driver instead of relying on the connection never dropping.
  • Keep long-running scripts (imports, migrations, bulk cron jobs) reconnecting periodically rather than holding one connection for the whole run.
  • Monitor MySQL's error log for unexpected restarts - a single "gone away" report is a config tweak, a recurring one is a resource problem.
  • If you manage your own VPS, keep innodb_buffer_pool_size sized to leave headroom for PHP-FPM and the OS, not maxed out to available RAM.

Most of the time this error is a five-minute config fix once you know which of the four causes you're dealing with. Check the MySQL error log first - it'll usually tell you within a few lines whether you're looking at a timeout, a packet size limit, or an actual crash.

Frequently asked questions

Does raising wait_timeout fix this permanently?

It reduces how often you hit the error, but it treats the symptom. If a script is holding a connection open for minutes at a time, fix that code path - raising the timeout just delays the next occurrence under heavier load.

Why does this happen during a database import specifically?

Large SQL dumps often contain single INSERT statements bigger than the default max_allowed_packet (commonly 4-16MB). MySQL drops the connection instead of returning a clear error, so import via SSH with mysql --max_allowed_packet=256M rather than through phpMyAdmin.

Is this the same as 'Error establishing a database connection' in WordPress?

No. That error usually means MySQL can't be reached at all (wrong credentials, MySQL not running, or wp-config.php misconfigured). 'Gone away' means a connection was established and worked, then died mid-session.

Can a WordPress plugin cause this?

Yes - plugins that make slow external API calls (payment gateways, import tools, SMTP senders) while holding a database connection open are a common trigger, especially combined with an aggressive CloudLinux wait_timeout on shared hosting.

How do I know if it was an OOM kill versus a timeout?

Run dmesg | grep -i 'killed process' | grep -i mysql. If MySQL shows up there, it was killed for memory - that's a resource issue, not a timeout setting, and needs more RAM/swap or a smaller innodb_buffer_pool_size.

#mysql #mysql-server-has-gone-away #wait-timeout #max-allowed-packet #database-error #wordpress

Keep reading

Chat with Support