ConnectException: Connection refused, explained and fixed

java.net.ConnectException: Connection refused means the client reached the target machine, asked to open a connection on a specific port, and was turned away. That is precise information: the host is reachable (this is not a timeout and not a DNS failure), but no program accepted the connection, usually because the service is not running, is listening on a different port, or is bound to a different network interface than the one being contacted. A firewall configured to reject (rather than drop) produces the same answer.

The checks, in order

  1. Is the service running at all? Check on the server itself first (its process list, its own logs, its admin console). A crashed or never-started service explains most refusals, and no client-side change can fix it.
  2. Is it listening where you think? On the server, list listening sockets (netstat -ano on Windows, ss -tlnp on Linux) and confirm the port, and look at the bind address: 127.0.0.1 accepts only local connections, 0.0.0.0 accepts all interfaces. A service bound to localhost refuses remote clients while working perfectly from the server itself.
  3. Verify the client is asking for the right place: the host and port in the connection string or configuration, including environment-specific overrides (a config file pointing at a development port in production is a classic). Test the same endpoint with a neutral tool (curl, a browser for HTTP services) from the same machine as the Java client.
  4. Then consider firewalls and security groups: host firewalls and cloud security groups that reject connections produce refusals; ones that drop produce timeouts instead, and that difference tells you which rule style to look for.

Frequent specific cases

  1. Database connections (JDBC): the database is down, still starting, or listening on a different port than the URL specifies; check the database's own log for “ready for connections” before suspecting the driver.
  2. Local development: the backend was started on a different profile or failed on its own startup error (often a port already in use on its side), check its console output, not the client's.
  3. After a deployment: the service bound to a container-internal interface or the orchestration layer maps a different external port; verify from inside the same network segment as the client.
“Connection refused” and “Connection timed out” are different diagnoses. Refused means an answer came back, no listener or an explicit reject, and is usually quick to fix on the server. A timeout means no answer at all, which points at routing, dropping firewalls, or a wrong address. Conflating them sends the investigation to the wrong layer.

Common questions

It worked yesterday and refuses today, what changed? Most often the service stopped (a crash, a reboot that did not restart it, a deployment that failed) or its port or bind address changed. Start with the server's process list and logs; client code that worked yesterday is rarely the new problem.

Why does it work from the server itself but not from my machine? The service is bound to 127.0.0.1 or the host firewall allows only local traffic. The bind address in the service's configuration is the setting to change, followed by a restart.

Can this be a DNS problem? No. A DNS failure produces an UnknownHostException naming the host. Getting “connection refused” proves the name resolved and the machine answered.

Related errors

ERR_CONNECTION_REFUSED (browser) · Broken pipe · SSH: Connection refused