Fix Error Establishing a Database Connection (500) Step by Step
Site down with “Error establishing a database connection” or a bare 500? Walk through credential checks, MySQL restarts, connection limits, and repair steps—then know when Fixwebnode should take over.
If your site suddenly shows “Error establishing a database connection” or a blank 500 Internal Server Error, visitors cannot reach you and orders or leads stop cold. This guide is for homeowners and small businesses running WordPress or other PHP apps on a Linux VPS or shared host. You will verify credentials, confirm the database service is up, ease connection pressure, and repair damaged tables—with real shell commands you can paste.
When DIY hits a wall, Fixwebnode server support steps in on this exact outage path—not a generic marketplace. Coverage and remote help map across our service areas, including teams oriented to stacks like those used with Arizona software installation and Providence, RI Linux administration.
Why this error matters (and what it usually means)
The message means PHP cannot open a session to MySQL or MariaDB. The web server may still be running, so you get a database-specific page or a generic 500 depending on how errors are displayed. Typical triggers: wrong password after a host migration, the database daemon stopped after a reboot or OOM kill, too many open connections, a bad socket or host name, or corrupted InnoDB tables after a crash.
Treat this as an outage. Work in order: prove the DB process is alive, prove credentials and host match, then fix capacity or corruption. Always snapshot or export before destructive repair.
Common issues that cause “Error establishing a database connection”
These four root causes show up repeatedly on small-business sites. Symptoms differ so you can match your situation before changing configs.
- Wrong or stale credentials in the app config — After a restore, password rotate, or panel “change DB user” action,
wp-config.php(or.env) still has the old user, password, database name, or host. Symptom: error appears on every page; SSH login to the server still works. - MySQL/MariaDB service stopped or crashing — Reboot without enable, disk full, or OOM killer. Symptom: same error site-wide;
systemctl statusshows inactive or failed; error logs mention InnoDB or “Can't connect to local MySQL server through socket”. - Connection limit or “too many connections” — Traffic spike, stuck PHP-FPM workers, or a low
max_connections. Symptom: intermittent 500s or DB errors under load; some requests succeed; MySQL error log orSHOW STATUSshows connection refusals. - Corrupted tables or crashed InnoDB after unclean shutdown — Power loss, forced kill, or full disk mid-write. Symptom: error only on certain URLs or admin; logs show “Table is marked as crashed” or InnoDB recovery failures.
Fix 1 — Verify and correct database credentials
Most WordPress outages after hosting moves are simply mismatched DB name, user, password, or host. Confirm what the server actually accepts, then align the app file.
Step 1 — Locate the app config
On a typical WordPress document root:
sudo find /var/www -name wp-config.php 2>/dev/null
sudo nano /var/www/html/wp-config.php
Note DB_NAME, DB_USER, DB_PASSWORD, and DB_HOST (often localhost, 127.0.0.1, or a remote hostname).
Step 2 — Test login as the same user MySQL expects
sudo mysql -e "SELECT user, host FROM mysql.user;"
mysql -u YOUR_DB_USER -p -h 127.0.0.1 -e "SHOW DATABASES;"
If socket auth is required instead of TCP:
mysql -u YOUR_DB_USER -p -e "SHOW DATABASES;"
Success lists databases including yours. Failure means the password or host grant is wrong—not the web server.
Step 3 — Align grants and password if needed
sudo mysql
ALTER USER 'YOUR_DB_USER'@'localhost' IDENTIFIED BY 'NewStrongPasswordHere';
GRANT ALL PRIVILEGES ON your_db_name.* TO 'YOUR_DB_USER'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Update DB_PASSWORD (and host if you use 127.0.0.1 vs localhost) in wp-config.php, save, then reload the site.
Step 4 — Verify from PHP’s perspective
php -r '$m=@new mysqli("127.0.0.1","YOUR_DB_USER","YourPassword","your_db_name");
echo $m->connect_error ? $m->connect_error : "OK\n";'
Prints OK when credentials and host match. If only localhost fails, switch DB_HOST to 127.0.0.1 (forces TCP) or fix the socket path in MySQL config.
Call Fixwebnode when panel “DB user” tools disagree with the live MySQL users table, or when the host uses remote managed DB endpoints you cannot re-grant yourself.
Fix 2 — Restart and harden the database service
If the daemon is down, no correct password will help. Confirm status, free disk space, then start cleanly and enable on boot.
Step 1 — Check service and recent failures
sudo systemctl status mysql --no-pager
# or: sudo systemctl status mariadb --no-pager
sudo journalctl -u mysql -n 80 --no-pager
sudo tail -n 80 /var/log/mysql/error.log
Look for “out of memory”, “No space left on device”, or InnoDB assertion failures.
Step 2 — Confirm disk and memory headroom
df -h
free -m
sudo du -sh /var/lib/mysql
If the root or data partition is 100% full, free logs or backups before starting MySQL:
sudo journalctl --vacuum-size=200M
sudo truncate -s 0 /var/log/nginx/access.log
(Only truncate logs you understand; never delete /var/lib/mysql.)
Step 3 — Start and enable the service
sudo systemctl start mysql || sudo systemctl start mariadb
sudo systemctl enable mysql || sudo systemctl enable mariadb
sudo systemctl is-active mysql || sudo systemctl is-active mariadb
Expected: active.
Step 4 — Confirm the port or socket is listening
sudo ss -lptn | grep -E '3306|mysql'
mysqladmin -u root -p ping
mysqld is alive means the server accepts admin connections. Reload the website.
Book a specialist if the service enters a crash loop, InnoDB refuses recovery, or the data directory was moved without updating datadir in config.
Fix 3 — Relieve “too many connections” and stuck workers
When the site fails only at peak times—or recovers after a few minutes—the server may be hitting max_connections while PHP-FPM holds idle DB links.
Step 1 — Inspect live connection pressure
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections'; SHOW STATUS LIKE 'Threads_connected'; SHOW STATUS LIKE 'Max_used_connections';"
mysql -u root -p -e "SHOW FULL PROCESSLIST;"
If Threads_connected sits near max_connections, new PHP requests get the establishing-connection error.
Step 2 — Clear runaway sessions safely
mysql -u root -p -e "SHOW FULL PROCESSLIST;" | head
# Kill a stuck non-system thread by Id only after review:
mysql -u root -p -e "KILL 12345;"
Step 3 — Raise the ceiling modestly and persist it
mysql -u root -p -e "SET GLOBAL max_connections = 200;"
sudo mkdir -p /etc/mysql/conf.d
echo -e "[mysqld]\nmax_connections = 200" | sudo tee /etc/mysql/conf.d/zz-connections.cnf
sudo systemctl reload mysql || sudo systemctl restart mysql
Step 4 — Cap PHP-FPM so it cannot open more DB links than MySQL allows
sudo grep -R "pm.max_children" /etc/php/*/fpm/pool.d/
# Example edit for the www pool:
sudo sed -n '1,120p' /etc/php/8.2/fpm/pool.d/www.conf
sudo systemctl reload php8.2-fpm
Keep pm.max_children below a sensible fraction of max_connections (other system users need headroom). Recheck the site under light load, then monitor:
watch -n 2 'mysql -N -e "SHOW STATUS LIKE \"Threads_connected\";" 2>/dev/null || true'
Escalate to Fixwebnode when connection storms return every hour, you suspect a bot loop or plugin query storm, or tuning risks starving other apps on the same box.
Fix 4 — Repair crashed tables and check InnoDB health
Use this path when logs mention crashed MyISAM tables or InnoDB recovery, or only some post/product pages fail while the homepage sometimes loads.
Step 1 — Full file-level backup before repair
sudo systemctl stop mysql || sudo systemctl stop mariadb
sudo tar -czf /root/mysql-datadir-$(date +%F).tar.gz -C /var/lib mysql
sudo systemctl start mysql || sudo systemctl start mariadb
Step 2 — Logical dump if the server will start
mysqldump -u root -p --single-transaction --routines --triggers --all-databases | gzip > /root/all-dbs-$(date +%F).sql.gz
Step 3 — Check and repair (MyISAM-friendly; InnoDB needs care)
mysqlcheck -u root -p --auto-repair --all-databases
# Or one schema:
mysqlcheck -u root -p --auto-repair your_db_name
For a specific WordPress table set after identifying errors:
mysql -u root -p your_db_name -e "CHECK TABLE wp_posts, wp_options, wp_postmeta;"
mysql -u root -p your_db_name -e "REPAIR TABLE wp_posts, wp_options;"
Step 4 — InnoDB forced recovery only if the service will not start cleanly
Add a temporary recovery mode, start, dump, then remove it. Example snippet in a conf drop-in:
echo -e "[mysqld]\ninnodb_force_recovery = 1" | sudo tee /etc/mysql/conf.d/zz-recovery.cnf
sudo systemctl start mysql
# Dump immediately, then:
sudo rm /etc/mysql/conf.d/zz-recovery.cnf
sudo systemctl restart mysql
Raise innodb_force_recovery only one step at a time (1–4 range for read/dump). Do not leave recovery mode enabled in production. After a clean import onto a fresh datadir is safer than endless force-recovery writes.
Step 5 — Confirm application health
curl -sI https://your-domain.example | head -n 5
mysql -u YOUR_DB_USER -p -h 127.0.0.1 your_db_name -e "SELECT COUNT(*) FROM wp_options;"
HTTP 200 and a successful count mean the connection path and core tables respond again.
Stop DIY and contact Fixwebnode if force recovery above level 1 is required, dumps fail mid-export, or you lack a tested restore path—continued writes can destroy remaining recoverable pages.
When DIY is enough vs when to book Fixwebnode
DIY is enough when you have SSH or panel terminal access, a recent backup, clear credential mismatches, a stopped service that starts after freeing disk, or a modest max_connections bump that holds under normal traffic. Re-test after each change; do not stack five config edits at once.
Book Fixwebnode when the database crash-loops, managed cloud DB firewall rules block the app tier, replication or remote hosts are involved, malware rewrites wp-config.php, or the outage sits on a revenue site and you cannot risk deeper InnoDB recovery. Remote server support is the product framing here: same playbook as above, with escalation when root cause sits below the app layer.
If your stack spans multiple regions or you already work with install and Linux admin paths in places such as Arizona or Providence, start from the same service areas overview so the right on-call path is clear.
Get the site answering queries again
Work the sequence: credentials and host → service status and disk → connection capacity → table repair with backups first. That order fixes the majority of “Error establishing a database connection” and related 500 responses without guesswork.
If you want a specialist to finish isolation, recovery, or post-outage hardening, open a conversation through Fixwebnode Support and describe the exact error text, host type (VPS vs managed), and whether MySQL starts on the CLI. We will pick up from the step you reached—not from a blank ticket.