apache/seatunnel · warning

Collector authentication failed from {}

Error message

Collector authentication failed from {}

What it means

This warning is logged by the edge-socket ingress protocol handler when a collector presents an authentication token that does not match the configured token. The handler compares the presented token against config.getToken() using a constant-time comparison to avoid timing attacks, and on mismatch writes the AUTH_FAILED response code and refuses authentication. It is a deliberate, expected rejection path for unauthenticated clients, not an internal fault.

Source

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

            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 {
                record = channel.readLine();
            } catch (SocketTimeoutException timeoutException) {
                continue;
            }
            if (record == null) {
                return;
            }
            channel.writeLine(dispatch(record));

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Set the same token in the collector's auth line and in the edge-socket source config (token option).
  2. Inspect the collector's auth line format so parseAuthToken extracts the full token (check prefix, separators, and no trailing newline/CR).
  3. If tokens were rotated, redeploy collector config with the current server token.
  4. Enable debug logging on both sides to confirm the server received the auth line at all.

Example fix

// before (collector)
AUTH token=stale-rotated-token
// after (collector config)
edge.socket.token = current-server-token  # matches source config
Defensive patterns

Strategy: validation

Validate before calling

if (!Objects.equals(configuredToken, collectorToken) || configuredToken == null || configuredToken.isEmpty()) { throw new IllegalStateException("collector token does not match edge-socket source token"); }

Prevention

When it happens

Trigger: A collector socket connects, sends an auth line, and the parsed token from the auth line differs from the token configured on the edge-socket source; parseAuthToken returned something that failed constantTimeEquals against the configured token.

Common situations: Collector and server configured with different tokens (stale token in collector config after rotation), token with trailing whitespace/newline or wrong prefix on the collector side, collector pointing at the wrong environment (staging token vs prod server).

Understand the failure class

Related errors


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