← Debugging Guides

阅读中文版本

Java ConnectException: Connection refused

Diagnose Java java.net.ConnectException Connection refused by separating client, firewall, and remote-listener causes with telnet and netstat.

beginnerdebuggingjavanetworknetworking

Symptoms

  • java.net.ConnectException: Connection refused (Connection refused)
  • The client fails immediately rather than timing out
  • It works from one machine but not another

Possible causes

  • Nothing is listening on the target host and port
  • The service binds only to 127.0.0.1, not the external interface
  • A firewall rejects the connection with a reset
  • The port number is wrong or the service failed to start

Diagnosis steps

Test the port directly from the client host

telnet host 8080  # or nc -vz host 8080

Interpretation

An immediate refusal confirms no listener or a firewall reset, unlike a timeout which suggests filtering.

Check what the remote host is listening on

ss -ltnp | grep 8080

Interpretation

Binding to 127.0.0.1 versus 0.0.0.0 explains why local calls work but remote ones are refused.

Verify the service actually started

systemctl status myapp

Interpretation

A crashed or not-yet-started service is a common cause after a deploy.

Root cause

ConnectException with Connection refused means the TCP SYN received a RST: the target port has no listener, or a firewall actively rejected it. It is distinct from a timeout, which indicates packets were dropped silently. A service bound to loopback only refuses connections arriving on other interfaces.

Fix

Start the service and bind it to the intended interface (0.0.0.0 or the specific address). Open the firewall rule and confirm no security group blocks the port. Correct the host/port in configuration, and add connection retries with backoff so a transient startup delay does not fail the deploy.

Verify the fix

From the client host, run telnet/nc again; the port accepts a connection, and the Java client completes the call without ConnectException.

Symptoms

A call fails fast with java.net.ConnectException: Connection refused. The immediate failure distinguishes it from a timeout, and it may affect only one host or one port.

Diagnosis

Probe the port and check the listener:

nc -vz app.internal 8080
ss -ltnp | grep 8080

If the remote shows 127.0.0.1:8080, it is loopback-only and remote clients are refused.

Fix

Bind to the right interface and open the port:

server:
  address: 0.0.0.0
  port: 8080

Add retry with backoff in the client for transient startup gaps:

for (int i = 0; i < 5; i++) {
    try { return connect(); }
    catch (ConnectException e) { Thread.sleep(200L << i); }
}

Verification

Re-run the probe from the client host; the port accepts connections and the Java call succeeds without the exception.

Additional Notes

A refusal and a timeout point in different directions, so the immediate reset characteristic of a refusal is itself diagnostic: it means the target host was reachable but no one accepted the connection. Verifying which interface the service bound to explains why a local call succeeds while a remote one fails, and confirming the listener exists distinguishes a stopped service from a firewall rule. Building in connection retries with backoff also smooths over the brief window after a restart when the port is not yet accepting traffic.