apache/seatunnel · error · IOException

Cannot connect to edge ingress

Error message

Cannot connect to edge ingress ${endpoint} after ${maxReconnectCycles} cycles

What it means

EdgeTransportClient.ensureAuthenticatedSession exhausts its bounded reconnect loop (maxReconnectCycles attempts with exponential backoff) without establishing an authenticated session to the edge ingress endpoint, then throws IOException. It fails fast instead of retrying forever when the ingress is unreachable or keeps rejecting the handshake.

Solutions

  1. Verify the edge ingress endpoint is reachable from the agent (curl/telnet host:port) and fix the endpoint config.
  2. Check agent logs for the per-attempt failure reason (DNS, TLS, auth) and fix the root cause.
  3. Increase initialBackoffMs/maxBackoffMs and maxReconnectCycles if the ingress is slow to start (rolling deploys).
  4. Add an outer retry/fallback so the agent degrades gracefully instead of throwing a single IOException.

Example fix

// before
client.open(); // throws IOException after maxReconnectCycles
// after
try {
    client.open();
} catch (IOException e) {
    LOG.warn("edge ingress unreachable, will retry in 30s", e);
    scheduler.schedule(client::open, 30, TimeUnit.SECONDS);
}
Defensive patterns

Strategy: retry

Validate before calling

boolean reachable = false;
try (Socket s = new Socket()) {
    s.connect(new InetSocketAddress(host, port), 3000);
    reachable = true;
} catch (IOException ignored) {}
if (!reachable) throw new IllegalStateException("edge ingress " + host + ":" + port + " unreachable before open()");

Try / catch

try {
    client.open();
} catch (IOException e) {
    LOG.log(Level.SEVERE, "edge ingress connect failed after reconnect cycles", e);
    scheduleReconnectWithCap();
}

Prevention

When it happens

Trigger: open() or sendUntilReceived() calls ensureAuthenticatedSession; every connect/auth attempt across maxReconnectCycles cycles fails (endpoint down, DNS failure, TLS rejection, auth rejected).

Common situations: Edge ingress not deployed or crashed; wrong endpoint host/port in agent config; network partition or firewall blocking the socket; credentials misconfigured so handshake auth never succeeds.

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


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/0dbe620e1476827d. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-edge-agent/seatunnel-edge-agent-transport/src/main/java/org/apache/seatunnel/edge/agent/transport/socket/EdgeTransportClient.java:194

                }
                throw ex;
            } catch (IOException connectOrAuthEx) {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException closeEx) {
                        LOG.debug("Error closing socket after connect/auth failure", closeEx);
                    }
                }
                LOG.warn("Connect/auth failed for {}", endpoint, connectOrAuthEx);
                backoff =
                        Math.min(
                                config.getMaxBackoffMs(),
                                Math.max(backoff, config.getInitialBackoffMs()) * 2);
                EdgeTransportConfig.sleepQuiet(backoff);
            }
        }
        throw new IOException(
                "Cannot connect to edge ingress "
                        + endpoint
                        + " after "
                        + config.getMaxReconnectCycles()
                        + " cycles");
    }

    private static final class SocketHolder implements AutoCloseable {
        private final Socket socket;
        private final BufferedReader reader;
        private final BufferedWriter writer;

        SocketHolder(Socket socket, BufferedReader reader, BufferedWriter writer) {
            this.socket = socket;
            this.reader = reader;
            this.writer = writer;
        }

View on GitHub (pinned to cf67b549a7)