Error establishing a database connection: how to fix it
Kofi Agyem, Founder and CEO, CloudzyroPublished · 7 min read
On this page
Why WordPress shows Error establishing a database connection and how to fix it: wp-config.php, cPanel prefixes, MySQL limits, and Supabase or Neon apps.
1. The short answer
"Error establishing a database connection" means WordPress tried to sign in to its database and couldn't. Most of the time, one of the four values in wp-config.php is wrong: the database name, the username, the password or the host. Otherwise the database server is down, overloaded or out of connections.
Your content is almost certainly still there. Fix the connection and the site comes back as it was. The same idea applies to Node.js and other apps: the connection string is wrong, the database can't be reached, or it's full.
2. What WordPress needs to connect
Every WordPress page load starts by reading wp-config.php in the site's folder and connecting to MySQL or MariaDB with these settings:
define( 'DB_NAME', 'myacct_wp' );
define( 'DB_USER', 'myacct_wpuser' );
define( 'DB_PASSWORD', 'the-database-users-password' );
define( 'DB_HOST', 'localhost' );If any one is wrong, or the database doesn't answer, WordPress stops and shows the error. In the admin area you may see a different message, such as "One or more database tables are unavailable", which points to damaged tables instead.
3. Common causes
- Wrong details in `wp-config.php`. Common after moving a site, restoring a backup, or someone changing a password.
- The cPanel prefix is missing. cPanel puts the account's username and an underscore in front of every database and database user:
wpbecomesmyacct_wp. A config copied from another host won't have it. - The user isn't attached to the database. In cPanel, a database user does nothing until it's added to the database with privileges.
- Wrong `DB_HOST`. On cPanel it's almost always
localhost. An address from your old host won't work. - The database server is down or restarting.
- Too many connections. Traffic spikes, bots or a slow plugin leave connections open until MySQL refuses new ones (error 1040, or a per-user limit on shared hosting).
- Damaged tables, after a crash or a full disk.
- A full disk. When an account runs out of space, the database may not be able to write.
4. How to fix it in WordPress, step by step
- Open `wp-config.php` in cPanel's File Manager, over SFTP, or over SSH, and note the four values.
- Check the database exists. In cPanel, open MySQL Databases and find the exact name, prefix included. Copy it into
DB_NAME. - Check the user and its access. On the same page, under Current Users, confirm the user in
DB_USERexists, and under Current Databases that it's listed against your database. If not, use Add User To Database and grant All Privileges. - Reset the password if unsure. Change the database user's password in MySQL Databases and paste the same value into
DB_PASSWORD. Passwords are case-sensitive, and a single quote inside one needs escaping in PHP. - Set `DB_HOST` to `localhost` unless your host gives you another value.
- Test the login separately. Open phpMyAdmin from cPanel: if your databases appear, MySQL itself is running. Over SSH,
mysql -u myacct_wpuser -p myacct_wptests the exact user and password. - Repair damaged tables if the login works. Add
define( 'WP_ALLOW_REPAIR', true );towp-config.php, visit/wp-admin/maint/repair.php, run it, then remove the line. That page works without a login, so don't leave it on. - If it comes and goes, look at traffic and load: block bad bots, add page caching, and check slow plugins. Ask your host whether you're hitting a connection limit.
With SSH access, WP-CLI reads the same settings and gives clearer errors:
cd ~/public_html
wp config get DB_NAME
wp config get DB_USER
wp config get DB_HOST
wp db check # connects and checks the tables
wp db repair # repairs them if needed5. On Cloudzyro Web Hosting
Cloudzyro Web Hosting is cPanel, so everything above applies as written. Open cPanel from the console, and use MySQL Databases and phpMyAdmin to check names, users and access. Every account also has SSH with WP-CLI (wp), so the commands above work there.
One thing to know: Change password on the account's page in the console changes the password for cPanel, FTP and the account's databases. If your wp-config.php signs in with the account's main username, update DB_PASSWORD to the new one. Sites that use their own database user, as WordPress installers usually set up, aren't affected.
If a change goes wrong, cPanel's JetBackup keeps 30 days of backups you can restore yourself, including databases. More on PHP hosting.
6. The same error in Node.js and other apps
Apps that use Postgres or MySQL hit the same problem with different words. What each message usually means:
- `password authentication failed for user`: wrong user or password in the connection string. A password with
@,#or/must be URL-encoded. - `ENOTFOUND` or `getaddrinfo` errors: the host name is wrong, or it isn't set at all because the environment variable is missing.
- `ECONNREFUSED`: nothing is listening at that host and port. Often the app is still pointing at
localhostfrom your laptop. - `ETIMEDOUT` or `ENETUNREACH`: the database can't be reached, often because of an IP allow list or IPv6 (see below).
- `sorry, too many clients already` or `remaining connection slots are reserved`: the database is out of connections. Use a pooler and a small pool size in your app.
- SSL errors such as `no encryption` or `self-signed certificate`: the provider requires TLS. Add
sslmode=requireto the connection string or turn on SSL in your driver.
First check the app has the variable at all. A connection string in your local .env file doesn't travel with your code: it has to be set on your host as an environment variable.
7. Supabase and Neon: IPv6, poolers and SSL
Supabase gives each project a direct connection, db.[PROJECT-REF].supabase.co:5432. Supabase's docs say direct connections are on IPv6, or IPv4 only if the project has the IPv4 add-on. Many servers and hosting platforms have no IPv6, so the connection times out or fails with ENETUNREACH.
The fix is Supabase's Supavisor pooler, which works over IPv4:
- Session mode:
aws-[INDEX]-[REGION].pooler.supabase.com:5432, for long-running servers. - Transaction mode: the same host on port
6543, for serverless functions and many short connections. It doesn't support prepared statements, so turn them off in your driver or ORM. - The username changes: pooled connections use
postgres.[PROJECT-REF], not plainpostgres.
Copy the pooler string from your project's Connect button rather than editing the direct one by hand.
Neon gives each branch a direct and a pooled connection string; the pooled host has -pooler in its name. Neon requires TLS (sslmode=require), and a compute that has scaled to zero takes a moment to wake, so give your driver a connection timeout of a few seconds rather than one.
8. On Cloudzyro Sites & Apps
On Cloudzyro Sites & Apps, connect your database on the site's Database tab. Paste a connection string, key or .env lines, or use Connect Supabase, and the console tests the connection and saves the variables with the names your code reads. If you paste a Supabase direct connection string, it switches it to one your site can use. See how to connect Supabase.
If your database only allows listed addresses, add 173.234.137.161, where Cloudzyro sites run. A site that can't reach its database usually fails to start, and the console shows it as Crashed on start with the reason; the previous version stays online. A crash at startup behind a proxy is also a common source of a 502 error.
9. How to check
Test the exact connection string from your own machine, outside the app:
# Postgres (Supabase, Neon and others)
psql "postgresql://user:password@host:5432/dbname?sslmode=require" -c "select 1"
# MySQL on the hosting server itself (over SSH)
mysql -u myacct_wpuser -p -h localhost myacct_wp -e "select 1"If that works and the app still fails, the app isn't getting the same values: check the environment variable names and redeploy. If it fails too, the error message tells you which part (host, password or SSL) to fix.