You load your site and get a plain white page with one line of text: Error establishing a database connection. If you visit /wp-admin/ you may instead see One or more database tables are unavailable. The database may need to be repaired.
WordPress keeps every post, page, user and setting in a MySQL or MariaDB database. This error means PHP loaded WordPress, read wp-config.php, tried to log in to that database and failed, or logged in and found the core tables unreadable. Your content is almost always still there. Something between WordPress and the database is broken, and the steps below find it from the most likely cause to the least likely.
Before you start
- Back up first. Download a copy of
wp-config.php before you edit it. If your host offers snapshots or a backup tool, take one now, even though the site is down.
- Access you need: your hosting control panel (for the database list, users and phpMyAdmin), SFTP or the panel file manager, and ideally SSH with WP-CLI (the WordPress command line tool, run as
wp). Some hosts name the binary differently or do not offer SSH at all; everything here can also be done from the panel.
- Where to run the commands. Commands in gray boxes that start with
wp, mysql, df or du run in an SSH terminal, from the site’s folder (the one that contains wp-config.php). Most hosting panels offer a terminal or SSH access; on some hosts the command is wp-cli instead of wp. Blocks that start with define( are not commands: they are lines in wp-config.php, which you edit in the file manager or over SFTP. Words in CAPITALS inside a command are placeholders for your own values, explained under each box.
- Note the time. Write down when the error started and anything that changed just before it: a migration, a password change, a plugin update, a traffic spike. Your host will ask.
Step 1: Check the four database settings in wp-config.php
Open wp-config.php in the site root (the folder that contains wp-admin and wp-content). Find these lines:
define( 'DB_NAME', 'DATABASE_NAME' );
define( 'DB_USER', 'DATABASE_USER' );
define( 'DB_PASSWORD', 'DATABASE_PASSWORD' );
define( 'DB_HOST', 'localhost' );
In your file, DATABASE_NAME, DATABASE_USER and DATABASE_PASSWORD will be your site’s real values, and localhost may be a different address (Step 2 covers that). Change only the second value on each line, the one after the comma, and keep the quote marks around it.
Compare each value with the database section of your hosting panel. On shared hosting, database and user names often carry an account prefix (for example acct_wp), and a missing prefix is a common mistake after a move. Also confirm in the panel that the user is actually assigned to that database with full privileges. A user that exists but has no rights on the database fails exactly like a wrong password.
If you are not certain of the password, set a new one for the database user in the panel and paste the same value into wp-config.php. Watch for two traps: curly “smart” quotes pasted from a document or chat app, and a password containing a single quote, which must be written as \' inside the PHP string. Either one breaks the file or the login.
If WP-CLI is available, it can read your config without loading the rest of WordPress:
wp config get DB_HOST
wp db check
Type both exactly as shown: DB_HOST here is the name of the setting, not a placeholder. The first command prints the database address WordPress is using. wp db check logs in with the credentials from wp-config.php and runs a table check. A good result lists your tables with OK and ends with “Success: Database checked.” An “Access denied” message means the credentials are wrong. Note that it relies on the MySQL client tools being installed on the server, which some hosts do not provide.
Step 2: Make sure DB_HOST is the right kind of address
DB_HOST tells PHP where the database server is. It accepts several forms, and the right one depends on your host:
localhost: the database runs on the same machine. PHP connects through a local Unix socket file rather than the network. This is the most common value.
127.0.0.1: also the same machine, but over TCP on port 3306. Some servers only listen on one of the two, so switching between localhost and 127.0.0.1 can fix or cause this error.
localhost:3307 or db.example.net:3306: a host name plus a port, for a non-standard port or a separate database server.
localhost:/var/run/mysqld/mysqld.sock: a specific socket path, used when the socket is not where PHP expects it.
- A separate host name or private IP address: managed and container-based hosts often run the database on its own server, and some limit which addresses may connect.
After a migration, an old DB_HOST is a frequent culprit: the new host uses a separate database server and the file still says localhost, or the reverse. Use the exact value from your host’s documentation or panel.
Step 3: Test the login directly
If you have SSH, test the same credentials outside WordPress. This tells you whether the problem is WordPress or the database itself:
mysql -h DATABASE_HOST -u DATABASE_USER -p DATABASE_NAME -e "SELECT 1;"
Replace DATABASE_HOST, DATABASE_USER and DATABASE_NAME with the DB_HOST, DB_USER and DB_NAME values from wp-config.php. Leave -p on its own with nothing after it: it tells mysql to ask for the password, so it never appears on screen or in your command history. -e "SELECT 1;" runs one harmless query and exits. If DB_HOST includes a port, such as localhost:3307, split it: -h localhost -P 3307 (capital P).
Enter the password when asked. Read the result carefully, because each failure message points somewhere different:
- A small table showing
1: the credentials work. Go back and compare wp-config.php character by character, then move on to Step 5.
ERROR 1045 (28000): Access denied for user: wrong user name or password, or the user is not allowed to connect from this host.
ERROR 1049 (42000): Unknown database: the database name is wrong or the database does not exist (for example, an import never finished).
ERROR 2002 (HY000): Can't connect to local MySQL server through socket or Can't connect to MySQL server: the database service is down, or DB_HOST points to the wrong place.
ERROR 1040 (HY000): Too many connections or ERROR 1203 mentioning max_user_connections: the server is up but out of connection slots. See Step 4.
No SSH? Open phpMyAdmin from your panel. If it cannot connect either, the problem is the database server, not WordPress.
Step 4: Check whether the database server is down or overloaded
Signs that the server is the problem: other sites on the same account show the same error, phpMyAdmin will not open, or the error comes and goes when the site is busy.
Too many connections. MySQL allows a fixed number of simultaneous connections (max_connections), and many hosts also cap connections per database user. Every PHP request holds a connection while it runs, so a traffic spike, an aggressive crawler, a brute force attack on wp-login.php or a slow query that keeps connections open can use them all up. Raising the limit treats the symptom. Look at the access log for the flood of requests behind it and block or rate-limit that traffic.
Database service stopped. On a VPS you manage yourself, check it with systemctl status mariadb or systemctl status mysql (run as root, or put sudo in front; which name works depends on which database your server runs). active (running) is healthy; inactive or failed means it has stopped. The same command shows the most recent lines of its log, so read those too. On shared or managed hosting you cannot restart it yourself: contact your host.
Out of memory. On small servers the operating system can kill the database process when memory runs out. The service log or the system log will show it. This keeps happening until memory use or the server size changes.
Step 5: Check for a full disk
A full disk is an easy cause to miss. InnoDB, the storage engine WordPress tables use by default, cannot write when the disk or your account quota is full, and the database may stop accepting connections or refuse to start. Check disk usage in your hosting panel, or over SSH:
df -h
du -sh ~/* 2>/dev/null | sort -h | tail
Type both as shown; there is nothing to replace. df -h lists each disk with sizes in readable units: a Use% at or near 100% is your problem. On shared hosting it may show the whole server rather than your account, so trust the panel’s quota figure if they disagree. The second line measures each folder in your home folder (~), hides permission warnings (2>/dev/null), sorts by size and shows the ten largest, biggest last.
Common space hogs are old backup archives stored inside the account, a wp-content/debug.log that has grown for months, cache folders and old staging copies. Free space by moving backups off the server first, then restart or ask your host to restart the database.
Step 6: Repair damaged tables
If the login works but WordPress reports that tables are unavailable, a table may be damaged, often after a crash or a full disk. Try WP-CLI first:
wp db repair
Run it as shown from the site’s folder. It asks the database to repair every table and lists each one; a line ending in OK is fine, and a note that the storage engine does not support repair is explained below.
Or use WordPress’s built-in tool. Add this line to wp-config.php, above the line that says “That’s all, stop editing”:
define( 'WP_ALLOW_REPAIR', true );
Then visit https://example.com/wp-admin/maint/repair.php, replacing example.com with your domain, and choose Repair Database. Remove the line as soon as you are done. That page works without a login, so anyone can trigger it while it is enabled.
Repair works on MyISAM tables. InnoDB tables do not support the repair command, and the tool will say so. Real InnoDB corruption needs your host, or a restore from backup.
Step 7: Rule out the less common causes
- Options table problems. If WordPress can log in but cannot read its core tables properly, it can show this same error. With WP-CLI, run
wp option get siteurl exactly as written (siteurl is the name of the setting). If it returns your address, the options table is readable. If it errors, check that $table_prefix in wp-config.php matches the prefix of the tables you see in phpMyAdmin. (A wrong prefix more often sends you to the WordPress install screen instead.)
- Multisite domain mismatch. On a multisite network, a
DOMAIN_CURRENT_SITE value that does not match the domain in the database can produce this error, which is common after a domain change.
- Missing PHP extension. If PHP lacks the
mysqli extension, WordPress shows a different message saying your PHP installation appears to be missing the MySQL extension. This usually follows a PHP version switch. Re-enable mysqli in your panel’s PHP settings. php -m in a terminal lists the PHP extensions that are loaded, but the command line may use a different PHP version than your website, so the panel’s PHP settings are the better check.
- A drop-in. A
wp-content/db.php file replaces WordPress’s database layer (some caching and query monitoring plugins add one). If it is left over from a removed plugin, rename it and test.
Step 8: Restore from a backup
If the credentials work, the server is healthy and repair does not help, restore the most recent database backup from before the error. Restore the database first and test before you touch the files, so you change one thing at a time.
When to contact your host
Contact your host when the credentials test fine but WordPress still fails, when phpMyAdmin will not connect, when several sites are down at once, or when you see connection limit or disk errors you cannot clear. Send them:
- The exact error text and the time it started, with your time zone.
- The output of the
mysql test from Step 3, or a note that phpMyAdmin also fails.
- Recent lines from your PHP error log around that time.
- What you already checked and changed, and anything that happened just before (migration, password change, traffic spike).
Never paste your database password into a ticket. Tell them which database and user the site uses and let them check from their side.