apache/seatunnel · error · FTPException

Client not connected

Error message

Client not connected

What it means

The FSDataOutputStream returned by create() wraps the FTP storeFileStream; on close(), if the underlying FTPClient is no longer connected it throws FTPException('Client not connected') instead of completing the upload, because the transfer's final status cannot be confirmed.

Solutions

  1. Investigate why the control connection dropped (server idle timeout, firewall, server restart) and adjust server-side timeouts
  2. Write data continuously or use smaller files so the connection does not idle out mid-transfer
  3. Enable FTP keep-alive if available and confirm the client host is not NAT-idled; retry the whole upload on a fresh connection
  4. Check FTP server logs around the failure time for the disconnect cause

Example fix

// before
// long client-side pause between writes -> server times out control connection
// after
// stream data promptly; wrap upload in retry with fresh create() on IOException/FTPException
Defensive patterns

Strategy: try-catch

Validate before calling

// Monitor control-connection health before/during long uploads
FTPClient c = connect();
if (!c.isConnected() || c.getReplyCode() == 421) {
    throw new IllegalStateException("FTP control connection unhealthy before upload");
}

Try / catch

try (FSDataOutputStream out = fs.create(path, true)) {
    out.write(data); // write promptly, avoid long idle gaps
} catch (FTPException | IOException e) {
    if (e.getMessage() != null && e.getMessage().contains("Client not connected")) {
        // retry whole upload on a fresh connection
        retryUpload(path, data);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Closing the output stream after the FTP control connection dropped — server-side idle timeout, network interruption, server restarting, or the connection killed by a firewall during the write.

Common situations: Long pauses while writing a large file causing the FTP server to time out the idle control connection; unstable network between client and server; server-enforced connection limits dropping the session.

Related errors


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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java:384

        if (parent == null || !mkdirs(client, parent, FsPermission.getDirDefault())) {
            parent = (parent == null) ? new Path("/") : parent;
            disconnect(client);
            throw new IOException("create(): Mkdirs failed to create: " + parent);
        }
        client.allocate(bufferSize);
        // Change to parent directory on the server. Only then can we write to the
        // file on the server by opening up an OutputStream. As a side effect the
        // working directory on the server is changed to the parent directory of the
        // file. The FTP client connection is closed when close() is called on the
        // FSDataOutputStream.
        client.changeWorkingDirectory(parent.toUri().getPath());
        FSDataOutputStream fos =
                new FSDataOutputStream(client.storeFileStream(file.getName()), statistics) {
                    @Override
                    public void close() throws IOException {
                        super.close();
                        if (!client.isConnected()) {
                            throw new FTPException("Client not connected");
                        }
                        boolean cmdCompleted = client.completePendingCommand();
                        disconnect(client);
                        if (!cmdCompleted) {
                            throw new FTPException(
                                    "Could not complete transfer, Reply Code - "
                                            + client.getReplyCode());
                        }
                    }
                };
        if (!FTPReply.isPositivePreliminary(client.getReplyCode())) {
            // The ftpClient is an inconsistent state. Must close the stream
            // which in turn will logout and disconnect from FTP server
            fos.close();
            throw new IOException("Unable to create file: " + file + ", Aborting");
        }
        return fos;
    }

View on GitHub (pinned to cf67b549a7)