apache/hadoop · error · ConnectException
Localhost targeted connection resulted in a loopback. No…
Error message
Localhost targeted connection resulted in a loopback. No daemon is listening on the target port.
What it means
ConnectException from NetUtils.connect when a connection to a local endpoint 'succeeded' but the local port equals the remote port and the local address equals the remote address — the rare TCP self-connect permitted by the RFC, possible only when the OS hands you an ephemeral source port identical to the (dead) destination port. Hadoop detects the loopback, closes the socket, and reports it as connection refused because the target daemon cannot have been listening. The log line 'Detected a loopback TCP socket, disconnecting it' precedes the throw.
Solutions
- Treat it exactly like connection refused: retry the connection with backoff — the ephemeral collision is transient
- Verify the target daemon is actually listening: 'ss -ltnp | grep <port>'
- In tests, drain/wait on the port between stop and start, or use SO_REUSEADDR-style hygiene, and shrink the ephemeral window collisions by not reusing the same port instantly
Example fix
// before
NetUtils.connect(socket, addr, timeout); // rare: ConnectException "Localhost targeted connection resulted in a loopback" -> test flakes
// after
for (int i = 0; i < 3; i++) {
try { NetUtils.connect(socket, addr, timeout); break; }
catch (ConnectException e) { /* loopback self-connect == refused: retry */ sleep(backoff); }
} Defensive patterns
Strategy: retry
Validate before calling
// Cannot be pre-validated deterministically (OS-dependent ephemeral pick), // but you can check the daemon is listening first: // ss -ltn | grep <port> (shell-level)
Try / catch
catch (ConnectException e) { /* loopback self-connect == refused */ wait(backoff); retry connect with a fresh socket; after N attempts, surface 'daemon not listening on <port>'; } Prevention
- Retry on ConnectException with backoff — the self-connect case cannot persist
- In tests, wait for the port to close before rebinding it
- Treat 'Localhost targeted connection resulted in a loopback' as connection refused for alerting purposes
When it happens
Trigger: Connecting to localhost:<port> while no daemon listens on <port> and the OS happens to allocate <port> as the ephemeral source port (probability ~1/ephemeral-range per attempt); repeated rapid stop/start of daemons in tests increases the chance.
Common situations: Integration tests that kill and restart NameNode/DataNode/ResourceManager in tight loops; a daemon crashing between the client's port check and its connect; flaky CI where the failure appears as 'connection refused' to a port the test just closed.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Illegal argument for connect()
- A mount path(file/dir) already exist with the requested path
- ACL ' ' not of expected form scheme:id:perm
- Address should be : , but it is
- Attempt to examine value multiple times.
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/1ca8cc283419ba57.
Report an issue: GitHub.
Appendix: source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetUtils.java:631
SocketIOWithTimeout.connect(ch, endpoint, timeout);
}
} catch (SocketTimeoutException ste) {
throw new ConnectTimeoutException(ste.getMessage());
} catch (UnresolvedAddressException uae) {
throw new UnknownHostException(endpoint.toString());
}
// There is a very rare case allowed by the TCP specification, such that
// if we are trying to connect to an endpoint on the local machine,
// and we end up choosing an ephemeral port equal to the destination port,
// we will actually end up getting connected to ourself (ie any data we
// send just comes right back). This is only possible if the target
// daemon is down, so we'll treat it like connection refused.
if (socket.getLocalPort() == socket.getPort() &&
socket.getLocalAddress().equals(socket.getInetAddress())) {
LOG.info("Detected a loopback TCP socket, disconnecting it");
socket.close();
throw new ConnectException(
"Localhost targeted connection resulted in a loopback. " +
"No daemon is listening on the target port.");
}
}
/**
* Given a string representation of a host, return its ip address
* in textual presentation.
*
* @param name a string representation of a host:
* either a textual representation its IP address or its host name
* @return its IP address in the string format
*/
public static String normalizeHostName(String name) {
try {
return InetAddress.getByName(name).getHostAddress();
} catch (UnknownHostException e) {
return name;View on GitHub (pinned to 2add963021)