apache/seatunnel · warning

Collector from closed connection before authentication

Error message

Collector from {} closed connection before authentication

What it means

A WARN logged by IngressProtocolHandler.authenticate when the collector closes the TCP connection before sending any authentication line — readLine() returns null. The connection is rejected with the AUTH_FAILED response code (write will fail harmlessly on a closed socket).

Solutions

  1. Verify only intended collector clients target the EdgeSocket ingress port.
  2. Check collector-side logs/errors for why it disconnected before authenticating.
  3. Filter out scanners/probes at the network layer if the port is exposed.
  4. If collectors crash, fix the collector's connection/auth send logic first.
Defensive patterns

Strategy: validation

Validate before calling

String line = channel.readLine();
if (line == null || line.isEmpty()) {
    // peer closed or sent nothing; do not proceed to token comparison
    return false;
}

Try / catch

if (authLine == null) {
    // peer closed before auth; nothing to recover client-side
    return false;
}

Prevention

When it happens

Trigger: channel.readLine() returns null because the remote peer closed the socket during the authentication phase of the EdgeSocket ingress handshake.

Common situations: Port scanners or health probes connecting and immediately disconnecting; collector crash or restart mid-handshake; collector-side network drop; wrong client connecting to the EdgeSocket port.

Understand the failure class

Related errors


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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-edge-socket/src/main/java/org/apache/seatunnel/connectors/seatunnel/edgesocket/protocol/IngressProtocolHandler.java:66

            log.warn(
                    "Unsupported auth type: {}, from {}",
                    config.getAuthType(),
                    channel.remoteAddress());
            return false;
        }
        String authLine;
        try {
            authLine = channel.readLine();
        } catch (SocketTimeoutException timeoutException) {
            channel.writeLine(EdgeSocketResponseCode.AUTH_FAILED.getCode());
            log.warn(
                    "Collector authentication timeout from {}, connection rejected",
                    channel.remoteAddress());
            return false;
        }
        if (authLine == null) {
            channel.writeLine(EdgeSocketResponseCode.AUTH_FAILED.getCode());
            log.warn(
                    "Collector from {} closed connection before authentication",
                    channel.remoteAddress());
            return false;
        }
        String presentedToken = parseAuthToken(authLine);
        if (!constantTimeEquals(config.getToken(), presentedToken)) {
            channel.writeLine(EdgeSocketResponseCode.AUTH_FAILED.getCode());
            log.warn("Collector authentication failed from {}", channel.remoteAddress());
            return false;
        }
        channel.writeLine(EdgeSocketResponseCode.ACK.getCode());
        return true;
    }

    public void receiveLoop(IngressChannel channel, BooleanSupplier isActive) throws IOException {
        while (isActive.getAsBoolean()) {
            String record;
            try {

View on GitHub (pinned to cf67b549a7)