Logo
WP Fix by Blimx

Anatomy of 'Error Establishing a Database Connection' in WordPress

Actualizado:
DatabaseDiagnostics

The error everyone fears

You refresh your WordPress site and instead of your home page, you see this:

Error establishing a database connection

Nothing else. No stack trace, no log line, no hint about what's wrong. This is the most feared error message in WordPress β€” and the most misunderstood. It almost always has one of five specific causes, and once you know how to look, you find the cause in under 5 minutes.

This article walks through what the error actually means, the five technical causes, the diagnostic flow we use, and how to prevent it from happening again.

What the error actually means

When WordPress boots, the very first thing it tries to do is connect to MySQL. The connection uses four pieces of information from your wp-config.php file:

define('DB_HOST', 'localhost');
define('DB_USER', 'wp_user');
define('DB_PASSWORD', 'pass123');
define('DB_NAME', 'wordpress_db');

WordPress passes these to PHP's MySQLi extension. If anything fails β€” wrong credentials, MySQL not running, network unreachable, too many existing connections β€” PHP returns an error and WordPress catches it and shows the generic "Error establishing a database connection" message.

The genericity is deliberate. Leaking the real error to visitors would help attackers. The real error is in the server log; visitors only see the generic.

Cause 1 β€” Wrong credentials

The most common cause by far. One of DB_HOST, DB_USER, DB_PASSWORD, or DB_NAME no longer matches what MySQL accepts.

When this happens

  • Someone rotated the MySQL password but forgot to update wp-config.php
  • A migration to a new host where the credentials are different
  • A hosting panel auto-rotated credentials for security
  • A typo introduced during a manual wp-config.php edit
  • File restore from a backup taken when credentials were different

How to verify

Connect to MySQL directly with the same credentials from the same server:

mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD -D $DB_NAME

If this command succeeds, credentials are correct and the issue is elsewhere. If it fails, you know which credential is wrong by the error message (Access denied for user..., Unknown database...).

Fix

Update wp-config.php with the correct values. If you don't know the correct values, get them from your hosting panel (cPanel β†’ MySQL Databases) or your password manager.

Cause 2 β€” MySQL is not running

The MySQL service itself is down. Less common than credential issues, but more dramatic.

When this happens

  • Server out of memory and Linux OOM killer terminated MySQL
  • A MySQL crash caused by a corrupt InnoDB tablespace
  • Manual systemctl stop mysql followed by forgetting to restart
  • A disk-full condition preventing MySQL from writing
  • Server reboot where MySQL is not configured to auto-start

How to verify

On the server:

systemctl status mysql       # or mariadb, or mysqld
ps aux | grep -i mysql
ss -tlnp | grep 3306         # is anything listening on the MySQL port?

Fix

systemctl start mysql
journalctl -u mysql -n 50    # check why it stopped

If MySQL won't start, the journal log tells you why. Common reasons: corrupt table requiring --innodb-force-recovery, ran out of disk space, missing mysql.sock file.

Cause 3 β€” Too many connections

MySQL has a hard cap on simultaneous connections (max_connections, default 151). When the cap is hit, new connection attempts fail.

When this happens

  • A traffic spike where many concurrent visitors all need DB connections
  • A plugin leaking connections (failing to close after use)
  • Multiple WordPress sites on the same MySQL server, sharing the limit
  • Long-running queries holding connections open while new ones queue up
  • A failed deploy that left worker processes orphaned

How to verify

mysql -e "SHOW STATUS LIKE 'Threads_connected';"
mysql -e "SHOW VARIABLES LIKE 'max_connections';"
mysql -e "SHOW PROCESSLIST;"

If Threads_connected is near max_connections, you have a saturation problem.

Fix

Short term: increase max_connections in my.cnf:

[mysqld]
max_connections = 300

Then restart MySQL. Note: increasing this consumes more memory. Each connection costs roughly 1MB at minimum, sometimes more.

Long term: find what's leaking. SHOW PROCESSLIST shows current queries; look for queries in Sleep state for long periods β€” that's a leak.

Cause 4 β€” User locked out by MySQL

MySQL can lock a user account if its password fails too many times (when password_history and password_reuse_interval are configured) or if the user is explicitly suspended.

When this happens

  • A brute-force attempt on the database account
  • A misconfigured backup script using wrong credentials and repeatedly failing
  • A security plugin rotating passwords and not updating the database user
  • A hosting provider's automated security response

How to verify

mysql -e "SELECT user, host, account_locked FROM mysql.user WHERE user='wp_user';"

Fix

ALTER USER 'wp_user'@'localhost' ACCOUNT UNLOCK;

Plus identify and fix what was triggering the lockout in the first place.

Cause 5 β€” Network or socket issue

DB_HOST of localhost uses a Unix socket; 127.0.0.1 uses TCP. If the socket file is missing or the TCP port is unreachable, the connection fails even though MySQL is running.

When this happens

  • MySQL was reinstalled with a different socket path
  • The socket file got deleted (cleanup script gone wrong)
  • A firewall rule is blocking port 3306 on TCP
  • Remote MySQL host is unreachable (network outage)
  • DB_HOST set to a hostname that doesn't resolve

How to verify

# Find the actual MySQL socket
mysql -e "SHOW VARIABLES LIKE 'socket';"

# Check if it exists
ls -la /var/run/mysqld/mysqld.sock

# TCP connectivity test
nc -zv $DB_HOST 3306

Fix

For Unix socket issues: update DB_HOST in wp-config.php to the explicit socket path:

define('DB_HOST', 'localhost:/var/run/mysqld/mysqld.sock');

Or switch to TCP:

define('DB_HOST', '127.0.0.1:3306');

For TCP issues: fix firewall, fix DNS, or move the database to a reachable host.

The 5-minute diagnostic flow

When the error appears, run this sequence:

# Step 1 β€” Can MySQL even be reached?
mysql -e "SELECT 1;" 2>&1

# If step 1 fails with "Access denied":
#   β†’ Credential issue (Cause 1) or locked user (Cause 4)

# If step 1 fails with "Can't connect":
#   β†’ MySQL down (Cause 2) or socket/network issue (Cause 5)

# If step 1 fails with "Too many connections":
#   β†’ max_connections saturation (Cause 3)

# Step 2 β€” Confirm WP credentials work
mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" -D "$DB_NAME" -e "SELECT 1;"

# Step 3 β€” Check WP-CLI from the WordPress directory
cd /var/www/yoursite && wp db check

These three steps narrow down the cause every time.

Prevention checklist

Once you've fixed the immediate problem, harden against recurrence:

  • Document the database credentials in your password manager, not just wp-config.php
  • Set auto-restart for MySQL: systemctl enable mysql
  • Configure MySQL max_connections based on real load + 50% headroom
  • Add monitoring on the Threads_connected MySQL variable; alert at 80% of max
  • Lock down outbound port 3306 access (only your WordPress server, not the public internet)
  • Schedule daily backups of wp-config.php separately from the rest (it contains the credentials needed to restore everything else)

Common mistakes when diagnosing

  • Assuming the issue is WordPress when it's MySQL β€” WordPress is reporting the error, but the cause is on the database side
  • Restarting MySQL without checking why it stopped β€” masks the underlying issue, will happen again
  • Increasing `max_connections` to 1000 β€” solves the symptom, leaves the connection leak
  • Editing `wp-config.php` without backing it up first β€” one typo and you lose access to all backups too
  • Resetting MySQL password to fix "Access denied" β€” only valid if you confirmed credentials are wrong; otherwise breaks more things

When to call a specialist

The "Error establishing a database connection" message is solvable in 5 minutes for someone who has seen all five causes. It's solvable in 5 hours for someone seeing it for the first time. For business sites, the difference between 5 minutes and 5 hours is the difference between negligible loss and significant revenue loss.

Database connection emergency? We're online within minutes. For deeper repair, see database connection failure and corrupted table recovery.