Troubleshooting & Common Errors

Resolving MySQL "Connection Refused" Error by Adjusting `bind-address` and Hostname

By the Domain India teamPublished 6 min read
Knowledge base article
Contents (5 sections)

A MySQL "Connection refused" error means nothing is listening where your client is knocking: the database server is not running, or it listens only on 127.0.0.1 while your script connects to the server's domain name or public IP address. On your own server (a VPS) you fix it by matching the hostname in your code to where MySQL listens, and only then, if you truly need remote access, by changing bind-address safely. This applies to a server you manage yourself; on shared hosting you can't change bind-address, and you don't need to.

For the full guide, see Understanding MySQL's bind-address setting

Our main guide, Understanding MySQL's bind-address setting, covers config file locations, safe remote access, SSH tunnels and a troubleshooting table. On shared hosting, read Resolving MySQL "Connection refused" for shared hosting clients instead.

Key takeaways

If your app runs on the same server as MySQL, set the database host to localhost or 127.0.0.1 and leave bind-address alone. Change bind-address only when another machine must connect, and then also create a user for that IP only, allow that IP only in the firewall, and require TLS. On Domain India shared hosting, port 3306 is closed from outside: use localhost in your code, and phpMyAdmin or an SSH tunnel for desktop tools.

1. First, fix the hostname

Most "Connection refused" errors come from code that connects to example.com or the server's public IP while MySQL listens only on localhost. If the app and the database are on the same server, point the app at localhost:

php
<?php
$conn = new mysqli('127.0.0.1', 'app_user', getenv('DB_PASSWORD'), 'app_db');
if ($conn->connect_error) {
    error_log('DB connection failed: ' . $conn->connect_error);
    http_response_code(500);
    exit('Database unavailable');
}

Log the real error and show visitors a generic message; printing the connection error to the page leaks details. Keep the password out of the file (an environment variable or a config file outside the web root).

2. Check that MySQL is running and where it listens

bash
sudo systemctl status mariadb     # or mysql / mysqld, depending on your install
sudo ss -ltnp | grep -E ':3306|mysqld|mariadbd'

127.0.0.1:3306 means local connections only. 0.0.0.0:3306 or *:3306 means every address. If nothing listens on 3306, the service is stopped or crashed: read its log with sudo journalctl -u mariadb -n 50.

3. Only if another machine must connect: change bind-address safely

For managing the database from your own computer, an SSH tunnel is safer and needs no change (section 4). If another server really must connect directly:

  1. Edit the [mysqld] section
    of the server config. On AlmaLinux or Rocky Linux with MariaDB that is usually /etc/my.cnf.d/mariadb-server.cnf; on Ubuntu with MySQL, /etc/mysql/mysql.conf.d/mysqld.cnf. Set bind-address to the address clients will use, or 0.0.0.0.
  2. Restart the service
    (sudo systemctl restart mariadb, mysql or mysqld) and check again with ss -ltnp.
  3. Create a user for that client IP only.
    CREATE USER 'app'@'203.0.113.25' IDENTIFIED BY 'a-long-random-password'; then GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app'@'203.0.113.25';. No FLUSH PRIVILEGES is needed after CREATE USER and GRANT.
  4. Open the firewall for that IP only.
    With firewalld: sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.25" port port="3306" protocol="tcp" accept' then sudo firewall-cmd --reload. With UFW: sudo ufw allow from 203.0.113.25 to any port 3306 proto tcp.
  5. Require encryption
    for the remote user (ALTER USER ... REQUIRE SSL;) so passwords never cross the internet in plain text.
Three things from older guides you should not do

Do not open port 3306 to the whole internet (ufw allow 3306/tcp), do not grant ALL PRIVILEGES to 'user'@'%', and do not switch SELinux off with setenforce 0. The old GRANT ... IDENTIFIED BY form was removed in MySQL 8; create the user first, then grant.

4. The safer route for desktop tools: an SSH tunnel

bash
ssh -N -L 3307:127.0.0.1:3306 user@your-server-ip

Leave it running and point MySQL Workbench, DBeaver or HeidiSQL at host 127.0.0.1, port 3307. MySQL stays on localhost. The walkthrough is in securing MySQL access with SSH tunnels.

5. On Domain India shared hosting

The database server on shared hosting is managed by us, so bind-address is not yours to change. Use localhost as the host in your website's config. Port 3306 is closed to outside connections on our shared servers, and adding your IP under Remote Database Access does not open it. Use phpMyAdmin, or an SSH tunnel: jailed SSH access is available on every shared hosting plan (cPanel, DirectAdmin, Webuzo); it is off by default, so ask support to enable it for your account. SSH login uses a key, not a password.

If you need a database that other servers reach directly, that is a job for your own server. Domain India VPS plans give you full root access and are self-managed by default:

VPS Starter
₹552.65/mo + GST
  • 1 vCPU
  • 2 GB DDR4 RAM
  • 64 GB NVMe SSD Storage
  • 2 TB Monthly Bandwidth
See plan details

The card shows the live list price, excluding 18% GST.

Why does MySQL say connection refused?

Nothing is listening at the address and port your client uses. Either the MySQL service is stopped, or it listens only on 127.0.0.1 while your code connects to the server's domain or public IP. Use localhost in code that runs on the same server.

Should I set bind-address to 0.0.0.0?

Only when another machine must connect directly, and only together with a firewall rule for specific IPs, a database user limited to those IPs and encrypted connections. For your own desktop tools an SSH tunnel is safer and needs no change.

Where is bind-address set on AlmaLinux?

With MariaDB on AlmaLinux or Rocky Linux it is usually in /etc/my.cnf.d/mariadb-server.cnf under the [mysqld] section. Restart the mariadb service after changing it.

Can I change bind-address on Domain India shared hosting?

No. The shared database server is managed by Domain India and port 3306 is closed from outside. Use localhost in your website's config, and phpMyAdmin or an SSH tunnel for desktop tools.

Does GRANT ... IDENTIFIED BY still work?

Not in MySQL 8 and later. Create the user with CREATE USER, then GRANT the privileges it needs on the one database it uses.

Ready to connect? On a VPS, follow the bind-address guide; on shared hosting, see how to connect to the MySQL database or ask us through a support ticket.

Still can't reach your database?

Tell us whether you are on shared hosting or a VPS, the tool you use and the exact error, and we will help you connect.

Open a support ticket

Ready when you are

Get cPanel hosting from ₹125/mo + GST

See plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
Fix MySQL Connection Refused: bind-address & Host