Linux Error Guide: 'could not connect to server' — Fix Database Connection Failures
Fix Linux database connection errors for PostgreSQL and MySQL: diagnose a stopped service, wrong socket path, listen_addresses binding, and firewall rules blocking the port.
- #linux
- #troubleshooting
- #errors
- #database
Stuck on this Linux Admins error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
From a Linux host, a client that can’t reach its database reports a connection error before any query runs. PostgreSQL’s psql shows:
$ psql -h 127.0.0.1 -U app -d appdb
psql: error: connection to server at "127.0.0.1", port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
MySQL/MariaDB, when connecting over the local Unix socket, shows:
$ mysql -u app -p
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
Both mean the same thing at the OS level: the client tried to reach the database endpoint — a TCP port or a Unix socket file — and nothing accepted it. The database process is down, listening somewhere else, using a different socket path, or blocked by a firewall.
Symptoms
psql/mysqlfails instantly withConnection refusedorCan't connect ... through socket.- The app logs
could not connect to server/ECONNREFUSEDon startup and won’t serve traffic. - Connecting works from the DB host over the socket but fails over TCP from another host (or vice versa).
Can't connect ... socket '/var/run/mysqld/mysqld.sock' (2)— errno 2 isENOENT, the socket file doesn’t exist.- Connection succeeds locally but remote clients are refused on port 5432/3306.
Common Root Causes
- Database service not running —
postgresql/mysqld/mariadbis stopped or crashed, so nothing listens. - Wrong or missing socket path — the client’s default socket (
/var/run/mysqld/mysqld.sock) differs from where the server actually created it (/tmp/mysql.sock). - Bound to localhost only — PostgreSQL
listen_addresses = 'localhost'or MySQLbind-address = 127.0.0.1refuses remote TCP clients. - Firewall blocking the port —
ufw/firewalld/nftables or a cloud security group blocks 5432/3306. - Wrong host/port in the client — connecting to the wrong address, or to TCP when only the socket is enabled.
- Auth rejected before connect —
pg_hba.confor MySQL host grants reject the client, appearing as a connection failure.
Diagnostic Workflow
Confirm the database service is actually running:
sudo systemctl status postgresql # or: mariadb / mysqld
sudo journalctl -u postgresql --since '15 min ago' | tail
Check what’s listening, on which address, and whether the socket file exists:
sudo ss -ltnp | grep -E ':5432|:3306' # TCP listeners + owning process
ls -l /var/run/mysqld/mysqld.sock # does the MySQL socket exist?
sudo ss -lxp | grep -E 'postgres|mysql' # Unix domain (socket) listeners
For PostgreSQL, verify the listen address and client auth config:
sudo -u postgres psql -c "SHOW listen_addresses;"
sudo -u postgres psql -c "SHOW port;"
sudo grep -vE '^\s*#|^\s*$' /etc/postgresql/*/main/pg_hba.conf | tail
For MySQL/MariaDB, confirm the bind address and the real socket path:
mysqld --verbose --help 2>/dev/null | grep -E '^(bind-address|socket)'
sudo grep -rE 'bind-address|socket' /etc/mysql/
Rule out a firewall for remote TCP failures:
sudo ufw status verbose; sudo firewall-cmd --list-all 2>/dev/null
nc -vz db-host 5432 # refused vs timeout from the client
Example Root Cause Analysis
An application container on the same host as MySQL failed at startup:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
Errno (2) is ENOENT — the socket file simply wasn’t there. Checking the service and the actual socket path exposed the mismatch:
$ sudo systemctl status mariadb # active (running)
$ ls -l /var/run/mysqld/mysqld.sock
ls: cannot access '/var/run/mysqld/mysqld.sock': No such file or directory
$ sudo grep -r socket /etc/mysql/
/etc/mysql/mariadb.conf.d/50-server.cnf:socket = /run/mysqld/mysqld.sock
The server was healthy but created its socket at /run/mysqld/mysqld.sock, while the client defaulted to /var/run/mysqld/mysqld.sock. On this system /var/run was a symlink to /run, but the client library had been configured with a stale path that no longer resolved. Pointing the client at the correct socket resolved it:
mysql -u app -p --socket=/run/mysqld/mysqld.sock
# or set 'socket = /run/mysqld/mysqld.sock' in the [client] section of my.cnf
Had ss shown no listener at all, the fix would have been starting the service; a bind-address = 127.0.0.1 with remote clients would have called for binding to 0.0.0.0 plus a firewall rule.
Prevention Best Practices
- Keep the database service
enabledso it restarts on boot and after crashes; alert on unit failures. - Align client and server socket paths explicitly in
my.cnf/connection strings rather than relying on defaults. - Set
listen_addresses/bind-addressintentionally:localhostfor local-only, a specific interface or0.0.0.0for remote access. - Manage firewall/security-group rules for 5432/3306 in version control and open them only to trusted sources.
- Configure
pg_hba.confand MySQL grants for the exact client host/method so auth doesn’t masquerade as a connection failure. - Add a startup health check that connects to the DB and fails fast with a clear message instead of a raw driver error.
Quick Command Reference
sudo systemctl status postgresql|mariadb # is the DB running?
sudo ss -ltnp | grep -E ':5432|:3306' # TCP listeners + address
sudo ss -lxp | grep -E 'postgres|mysql' # Unix socket listeners
ls -l /run/mysqld/mysqld.sock # does the socket file exist?
sudo -u postgres psql -c "SHOW listen_addresses;"
nc -vz <db-host> 5432 # reachability from the client
sudo ufw status verbose # firewall rules
Conclusion
A database “connection refused” or “can’t connect through socket” error is an OS-level endpoint failure, not a query problem. Work through four checks in order: is the service running, is it listening on the address or socket path the client expects, does a firewall block the TCP port, and does client auth allow the host. The errno hints help — MySQL’s (2) is a missing socket file, Connection refused is a missing TCP listener. With systemctl status, ss, and the server’s own listen_addresses/socket settings, you can pinpoint which layer is failing in a couple of commands.
Fixed it? Get 500 Linux Admins & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.