One line of text on a white page: “Error establishing a database connection”. Every page, including wp-admin. No menu, no logo, no way in.
It is a blunt message but a precise one. WordPress keeps your content in a separate database, run by software called MySQL, and asks it for the page every time someone loads one. This message means the request never got through. Your posts, orders and users have not gone anywhere, and in most cases neither has the database.
There are about six reasons this happens, and you work through them in a fixed order. Keep to that order, because the most common advice, repairing the tables, is near the bottom of my list and is the one step that can make things worse.
You do not need to be a developer for this. Most of it is reading a settings file called wp-config.php, comparing four lines against what your hosting panel says, and running one small test.
Before you start
Gather these before you touch anything:
- A way to read and edit
wp-config.php. Either FTP or SFTP (ways of connecting to your server’s files with a program like FileZilla, SFTP being the secure one), or your hosting panel’s File Manager, which is easier if FTP is new to you and needs nothing installed. - Your hosting control panel login, for database users and service status
- phpMyAdmin, or whatever your host calls its database tool. It is a web page in your hosting panel that lets you look inside the database directly, without going through WordPress.
- The credentials as the host issued them, not as you remember them
Take a database backup if you can still get one. If phpMyAdmin opens and shows your tables, use its Export tab with the default settings now, before you change a thing. Two minutes there is the difference between an inconvenience and a disaster if a later step goes wrong. If the database is unreachable, check for automatic host backups.
Do not run any repair operation until you have a backup, or have confirmed one exists. Repair is not a safe default, whatever the search results say.
Step 1: Work out which failure you are actually looking at
The exact wording tells you a lot, so read it before doing anything.
The error on every page, front end and admin. WordPress cannot connect at all: credentials, host value, or the server itself. The common case, and Steps 2 to 5 cover it.
The front end errors, but /wp-admin/ says “One or more database tables are unavailable.” Better news. WordPress connected and then found specific tables missing or unreadable. Skip to Step 6.
You get redirected to the installation screen. WordPress connected fine and found no tables it recognises. Tables are the filing drawers inside a database, one for posts, one for users, and so on. Either the database is empty, or, far more likely, $table_prefix does not match the tables that are there. That is a line in wp-config.php saying what every table name starts with. Check the real names in phpMyAdmin (you might see wp_abc123_posts rather than wp_posts) and set $table_prefix to match.
That distinction matters. “Cannot reach the database” is about credentials and networking. “Reached it, found nothing” is about prefixes, imports and backups. Same-looking outage, different fix.
Step 2: Check whether the server is simply down
Before editing anything, rule out the possibility that this is not your problem to fix.
Check your host’s status page. Database outages on shared hosting hit many sites at once and are usually acknowledged within minutes. If you have other sites on the account, load one. If they are all down, it is the server.
Then open phpMyAdmin from your control panel. If phpMyAdmin cannot connect, WordPress was never going to either, and editing wp-config.php will not help. If phpMyAdmin does connect, turning on debug logging will show you the underlying MySQL error instead of the polite one-liner.
Two host-side causes are worth naming, because neither is a WordPress bug. A full disk quota stops MySQL writing and can take it offline. An unpaid invoice or a resource suspension does the same while looking like a technical fault.
Step 3: Check the credentials in wp-config.php against what the host issued
Open wp-config.php. It sits in the site root, the top-level folder that also holds wp-content and wp-admin, usually called public_html or httpdocs. Use your hosting panel’s File Manager, or download it over SFTP and open it in a plain text editor such as Notepad or TextEdit. Not Word.
Save a copy of the original first. If an edit goes wrong you put the copy back and you are no worse off than you are now. Near the top you will find four definitions:
define( 'DB_NAME', 'yoursite_wp' ); // Database name
define( 'DB_USER', 'yoursite_wpuser' ); // Database username
define( 'DB_PASSWORD', 'the-actual-password' );
define( 'DB_HOST', 'localhost' ); // Where MySQL lives
Open your hosting panel, find the database section (usually MySQL Databases) and compare all four against what is there, character by character. The failures here are boring and easy to miss.
Missing account prefix. cPanel and most shared panels prepend your account name to the database and the user, so the database you created as wp is really yoursite_wp. If someone typed the name they chose rather than the panel’s, this is your bug.
Trailing whitespace. A password copied from a welcome email often brings a space or line break with it. Retype it rather than pasting.
Unescaped characters. These are single-quoted PHP strings, so a backslash or apostrophe needs escaping: pa'ss\word must be written 'pa\'ss\\word'. Resetting the password to something long and alphanumeric is quicker than reasoning about escaping.
The wrong site’s credentials. Copying wp-config.php between staging and live is a classic. If the site was recently migrated or cloned, assume this until proven otherwise.
Correct anything wrong and reload the site.
Step 4: Test the credentials independently
If the details look right and the error persists, test them directly. This tells you whether the credentials are wrong or something else is. The whole problem forks here.
This step is safe: you are adding a new file, not changing one, so it cannot break anything. Create db-test.php in the site root with your real values, using your File Manager’s “New file” button or by writing it on your computer and uploading it:
<?php
// Temporary connection test. Delete this file as soon as you are done.
mysqli_report( MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT );
try {
$link = new mysqli( 'localhost', 'yoursite_wpuser', 'the-actual-password', 'yoursite_wp' );
echo 'Connected. Server version: ' . $link->server_info;
} catch ( mysqli_sql_exception $e ) {
// That reporting mode is the default from PHP 8.1 onwards, and the line
// above sets it explicitly so older versions also fail loudly rather
// than quietly. Either way the real reason arrives here.
echo 'Failed: ' . $e->getMessage();
}
Load https://yoursite.com/db-test.php, read the result, then delete the file immediately. It holds your database password in plain text in a public folder.
The message you get back is the point of the exercise:
- “Access denied for user…”: the username or password is wrong, or the user has no rights on that database. Step 5.
- “Unknown database…”: the user is fine, but the database name is wrong or the database has been deleted.
- “Can’t connect to MySQL server…” or a timeout:
DB_HOSTis wrong or the server is unreachable. Step 5. - “Too many connections”: the server is up but at its limit. Also Step 5.
- “Connected”: the credentials are correct and your problem is elsewhere. Step 6.
If your host gives you SSH, a text-only command line on the server, WP-CLI does the same job faster. Plenty of shared hosting has no SSH, and the test file above is a complete substitute, so skip this if it means nothing to you:
# Attempts a real connection using the values WordPress reads.
wp db check
Step 5: Fix the host value, the connection limit, or the user
DB_HOST is wrong
DB_HOST is the address WordPress dials to reach the database. localhost means “the same machine I am running on”. It is right on most shared hosting and wrong on plenty of other setups, because the value depends on where MySQL lives relative to PHP.
localhostconnects through a Unix socket, a direct internal channel between two programs on one machine.127.0.0.1also means the same machine, but goes through the network layer instead. Not the same thing, and on some setups one works while the other does not.- A hostname such as
mysql.yourhost.comis required when the database runs on a separate server, as it does on cloud and most managed platforms. - A non-standard port is appended with a colon:
mysql.yourhost.com:3307. - A socket path is given the same way:
localhost:/var/run/mysqld/mysqld.sock.
The correct value is in your host’s documentation. Do not guess. If you migrated hosts and updated only the username and password, DB_HOST is very often the line that was missed.
The server is at its connection limit
“Too many connections” or “max_user_connections” means MySQL is running but refusing new ones. On shared hosting there is a per-account cap, and one slow query or a traffic spike can exhaust it, at which point every site on the account throws this error.
It often clears on its own as connections close. If it keeps returning, the cause is usually a heavy query on every page load, a bot, or a plugin polling the database too often. That is a performance problem in disguise, and raising the limit only buys time.
The database user has been deleted or lost its privileges
If Step 4 said “access denied” and the password is definitely right, look at the user in the hosting panel. Two things happen in the real world: someone tidying up deletes a user that looked unused, and a compromised or suspended account has its database users removed.
Create a user, give it a strong password, grant it all privileges on that database (never on all databases), and put the new details into wp-config.php. Granting is a separate step in most panels, and a user created without being attached produces the same “access denied”.
If you suspect a compromise, changing the password is the beginning and not the end. Assume file-level access too, and treat it as a hacked site clean-up rather than a config fix.
Step 6: Only now, repair the tables
Reach this step only if WordPress can connect and the complaint is specifically that tables are unavailable or corrupted. Repairing tables when the real problem is a wrong password wastes time, and running repair blind on an unbacked-up database is how a recoverable situation becomes an unrecoverable one.
The WordPress repair screen
WordPress has a repair tool built in, switched off until you switch it on. Add this above the comment near the bottom of wp-config.php reading “That’s all, stop editing”:
// Enables /wp-admin/maint/repair.php. Remove this the moment you are finished.
define( 'WP_ALLOW_REPAIR', true );
Then visit https://yoursite.com/wp-admin/maint/repair.php. Two buttons: “Repair Database” and “Repair and Optimize Database”. Use the first. Optimising is slower and is not what you came for.
This page requires no login. That is deliberate, since it has to work when you cannot log in, but anyone who finds the URL can trigger it while the constant is defined. Remove the line as soon as you are done.
Why repair often reports it cannot help
The repair screen runs CHECK TABLE on each of WordPress’s tables and only reaches for MySQL’s REPAIR TABLE on the ones that come back unhealthy. REPAIR TABLE works on only a few storage engines. A storage engine is the part of MySQL that writes the data to disk, and there is more than one. REPAIR TABLE handles older ones, MyISAM among them. The default has been a newer one, InnoDB, for many years, so on most sites you either get a list of tables reported as okay, or a repair that comes back saying the storage engine does not support it.
That is not a failure on your part. Table repair, as most articles describe it, does not apply to your database. InnoDB handles its own crash recovery, and when it cannot, the fix is a server-level operation or a restore from backup. Ask your host to check the MySQL error log rather than experimenting with recovery settings on a live database.
The phpMyAdmin route
phpMyAdmin does the same with more control: open the database, tick the tables, and choose “Repair table” at the bottom. The same engine limitation applies, so it is more useful here for diagnosis. Check the tables exist and that wp_posts holds roughly the number of posts you expect. A table that exists but reports zero rows tells a different story from one that is missing.
How to check it worked
Load the front page, then log into wp-admin and open Posts and Settings, General. If the site title and URL are correct and your posts are listed, WordPress is reading the right database.
Then save something. Edit a post, change nothing, and click Update. A user with partial privileges loads pages perfectly and fails silently on save, and you would rather find that now than when a customer checks out.
Finally, delete db-test.php if you created one, and remove the WP_ALLOW_REPAIR line. Both are security problems left in place.
When it does not work
The credentials test connects but WordPress still shows the error
Check you edited the wp-config.php that is actually in use. A staging copy, an old backup folder, or a config moved above the web root all put two versions in play. To prove which is live, add die( 'live config' ); just after the opening <?php of the file you edited. That tells PHP to stop and print those two words. Reload the site, and if you do not see them you are in the wrong file. Remove the line either way.
The error appeared straight after a migration
DB_HOST and $table_prefix are the lines people forget when moving hosts. Check both against the new server, not the old one.
Everything is right and it still will not connect
It is the server, and the host has logs you do not. Open a ticket and quote the exact message from the test script in Step 4. That is far more actionable than “my site is down”.
Common questions
Does this error mean my site has been hacked?
Usually not. Wrong credentials after a migration, a password change, or a server under load account for nearly all of these. Treat it as a possible compromise only if the database user has vanished or its password changed on its own.
Have I lost my content?
Almost certainly not. The error means WordPress could not open a connection, not that the data is gone. Open the database in phpMyAdmin and look at wp_posts. If your posts are listed, everything is intact and you are fixing a connection, not recovering anything.
Why does the error come and go?
Intermittent failures are nearly always resource pressure rather than configuration, because a wrong password is wrong every single time. Connection limits, a server under load, or a busy neighbour on shared hosting all produce this pattern. Note the times and give them to your host.
Is this my host’s problem or mine?
If phpMyAdmin cannot connect either, or other sites on the account are down, it is the host’s. If phpMyAdmin works and only WordPress fails, the fault is in wp-config.php and it is yours. Step 4 settles that in a minute.
Should I just restore a backup?
Only once you have established that the database itself is damaged or missing. Restoring does not help when the fault is a wrong password or an unreachable server, and it overwrites content added since the backup. Diagnose first, restore second.
Getting back online, and stopping it happening again
Most of these end in one of two places: a credential that no longer matches after a migration or a password change, or a database server having a bad day. Both are quick to confirm once you test the connection directly rather than reading wp-config.php and hoping. Five minutes on the Step 4 test file saves an hour of changing values at random.
The order is what to take away. Check the server, check the credentials, test them, fix the host value or the user, and only then think about tables. Repair is the last resort, it does not apply to most modern databases anyway, and it belongs after a backup.
If this keeps happening, find the cause rather than fixing it repeatedly. If you would rather hand it over while the site is down, WordPress fixes and repairs covers exactly this, and maintenance includes the backups that make a bad day survivable. Either way, take that backup now.