You're trying to connect to MySQL and it's not having it. Annoying, but I've fixed this exact thing for years. Here's the fix.
The quick fix: check if MySQL is actually running
On Linux (systemd):
sudo systemctl status mysql
If it's not running, start it:
sudo systemctl start mysql
And enable it to start on boot:
sudo systemctl enable mysql
On Windows:
- Open Services (services.msc)
- Find MySQL or MySQL80
- Right-click and start it
- Set startup type to Automatic
On macOS with Homebrew:
brew services restart mysql
Try connecting again. If it works, you're done. Most of the time it's just a stopped service. But if it still fails, move to the next step.
Firewall blocking port 3306
If the service is running and you're trying to connect from another machine (or even localhost using TCP instead of socket), port 3306 might be blocked.
On Linux (iptables/firewalld):
sudo firewall-cmd --zone=public --add-port=3306/tcp --permanent
sudo firewall-cmd --reload
Or for ufw (Ubuntu/Debian):
sudo ufw allow 3306/tcp
On Windows, check Windows Defender Firewall — add an inbound rule for port 3306.
If you're testing from the same machine, try using the socket instead of TCP:
mysql -u root -p -h localhost
If that works but mysql -u root -p -h 127.0.0.1 doesn't, it's a socket vs TCP issue — MySQL might not be listening on TCP at all. That's the next section.
Why this happens
MySQL stops for a bunch of reasons:
- A power failure or crash
- A server restart without setting MySQL to start automatically
- Out of disk space — MySQL refuses to start if the data directory is full
- A corrupted table during a crash — sometimes MySQL won't start until you repair it
- A config change that broke the startup (wrong bind-address, wrong port)
Firewall blocks usually happen when you're moving a dev setup to production and forget to open the port. Or someone added a security rule that's too strict.
Less common variations
1. MySQL running but not listening on all interfaces
MySQL's default bind-address is often 127.0.0.1. That means it only accepts connections from localhost. If you need remote access, change it in my.cnf (or my.ini on Windows):
[mysqld]
bind-address = 0.0.0.0
Then restart MySQL.
2. skip-networking is enabled
Some people enable skip-networking in the config for security. It disables all TCP connections — you can only connect via the Unix socket (local filesystem). Check your config for that line and comment it out if you need TCP.
3. MySQL 8 caching_sha2_password issues
If you're connecting from a client that doesn't support the new auth plugin (older PHP, Python, or Java libraries), you'll get an auth error, not a connection refused. But I've seen people confuse the two. Check the MySQL log:
sudo tail -f /var/log/mysql/error.log
Look for authentication plugin errors. If that's your problem, alter the user:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
4. Resource exhaustion
If MySQL runs out of memory or max_connections, it might refuse new connections but the service appears running. Check SHOW VARIABLES LIKE 'max_connections'; and your server's RAM usage.
Prevention so you don't see this again
- Set MySQL to auto-start on boot:
sudo systemctl enable mysql(Linux) or set the service to Automatic (Windows). - Monitor disk space with a tool like Nagios, Zabbix, or a simple cron job that checks
df -h /var/lib/mysql. - Test your firewall rules when you first set up a server — don't wait until you need a remote connection at 3 AM.
- Keep a local socket fallback — always test with
mysql -u root -p -h localhostfirst when troubleshooting. - Document your my.cnf changes — I can't tell you how many times I've seen someone comment out a line and forget about it.
- Use a Docker healthcheck if you're containerized — it'll restart the container if MySQL stops responding.
That's it. Nine times out of ten it's a stopped service or a firewall. Check those first, don't waste time editing configs you didn't change. If you've done all this and it still won't connect, check the MySQL error log — it'll tell you exactly what's wrong.