Refused on 5432 means nothing is accepting there: cluster not running, listening on localhost only, or wrong port. Postgres makes each of these easy to check directly.
systemctl status postgresql and journalctl -u postgresql -n 30 show a stop or a config rejection (e.g., a syntax error prevents startup after an edit).
Remote connections are refused until listen_addresses includes the network interface (or '*'). Check: psql -c 'SHOW listen_addresses;' while local.
Debian supports versioned clusters on 5433+; pg_lsclusters lists them and their actual ports.
systemctl status postgresql --no-pager; journalctl -u postgresql -n 30 --no-pager
ss -tlnp | grep 543; sudo -u postgres psql -c 'SHOW listen_addresses;'
# postgresql.conf: listen_addresses = '*' + pg_hba.conf: hostssl all all 10.0.0.0/8 scram-sha-256 then: systemctl reload postgresql
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=... postgres:16 # app containers on the same network: use the service hostname
A postgres that refuses config edits startup with FATAL hints — read the log line right after your change; it names the file and directive. Expose only with hostssl + scram in pg_hba; 'trust' for remote subnets is how databases get dropped.
Local connections use the unix socket; apps usually use TCP. If listen_addresses is localhost and the app is on another host, TCP is refused. Show it with SHOW listen_addresses and widen it plus a matching pg_hba rule.
Refused = an active rejection (nothing listening or REJECT rule). Timeout = dropped packets (firewall drop). That distinction tells you which layer to debug — ss -tlnp for the former, security groups for the latter.
Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.
Browse the template store →One-time. Yours to modify. Instant download from the NinjaOps template store.