{"record":{"id":"042fdcae47370c5e","repo":"apache/seatunnel","slug":"could-not-complete-transfer-reply-code-client","errorCode":null,"errorMessage":"Could not complete transfer, Reply Code - ${client.getReplyCode()}","messagePattern":"Could not complete transfer, Reply Code - (.+?)","errorType":"exception","errorClass":"FTPException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java","lineNumber":389,"sourceCode":"        client.allocate(bufferSize);\n        // Change to parent directory on the server. Only then can we write to the\n        // file on the server by opening up an OutputStream. As a side effect the\n        // working directory on the server is changed to the parent directory of the\n        // file. The FTP client connection is closed when close() is called on the\n        // FSDataOutputStream.\n        client.changeWorkingDirectory(parent.toUri().getPath());\n        FSDataOutputStream fos =\n                new FSDataOutputStream(client.storeFileStream(file.getName()), statistics) {\n                    @Override\n                    public void close() throws IOException {\n                        super.close();\n                        if (!client.isConnected()) {\n                            throw new FTPException(\"Client not connected\");\n                        }\n                        boolean cmdCompleted = client.completePendingCommand();\n                        disconnect(client);\n                        if (!cmdCompleted) {\n                            throw new FTPException(\n                                    \"Could not complete transfer, Reply Code - \"\n                                            + client.getReplyCode());\n                        }\n                    }\n                };\n        if (!FTPReply.isPositivePreliminary(client.getReplyCode())) {\n            // The ftpClient is an inconsistent state. Must close the stream\n            // which in turn will logout and disconnect from FTP server\n            fos.close();\n            throw new IOException(\"Unable to create file: \" + file + \", Aborting\");\n        }\n        return fos;\n    }\n\n    /** This optional operation is not yet supported. */\n    @Override\n    public FSDataOutputStream append(Path f, int bufferSize, Progressable progress)\n            throws IOException {","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java#L371-L407","documentation":"Thrown by SeaTunnelFTPFileSystem when closing an FTP output stream: the FTP client sent the write commands, but the server did not report a successful completion of the pending data transfer. It means the file content may not have been fully persisted on the FTP server, so the filesystem throws rather than silently reporting success on a truncated or failed upload.","triggerScenarios":"Closing the FSDataOutputStream returned by create() when client.completePendingCommand() returns false — typically caused by the server rejecting or aborting the STOR transfer (disk full, permission denied on target file, connection dropped mid-transfer, server-enforced quota).","commonSituations":"Uploading to an FTP server whose disk is full or whose user quota is exceeded; network interruption during a large file write; FTP server configured with file size limits; passive-mode/firewall issues that drop the data channel; writing to a directory where the user lacks write permission after the initial file creation handshake succeeded.","solutions":["Check the FTP server logs and disk space/quota for the target directory","Verify the FTP user has write permission on the target file path","Configure passive mode (and correct port range in the firewall) to keep the data channel alive","Increase connection/idle timeouts and retry the whole write operation","Check client.getReplyCode() in server logs (e.g. 452/553) to identify the server-side rejection"],"exampleFix":"// before\ntry (FSDataOutputStream out = fs.create(path)) {\n    out.write(bigBuffer);\n}\n// after\ntry (FSDataOutputStream out = fs.create(path)) {\n    out.write(chunk);\n    out.flush(); // flush periodically to surface transfer errors early\n}\n// and retry the entire write on failure instead of assuming partial success","handlingStrategy":"try-catch","validationCode":"// pre-flight: check server reachability and target writability\nif (!fs.exists(path.getParent())) throw new IllegalStateException(\"parent dir missing\");","typeGuard":"// Java: no dynamic type guard; guard state instead\nboolean safeToWrite(FTPClient client) { return client != null && client.isConnected(); }","tryCatchPattern":"try (FSDataOutputStream out = fs.create(path)) {\n    out.write(data);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"Could not complete transfer\")) {\n        // treat file as corrupt: delete partial file and retry whole write\n        fs.delete(path, false);\n    }\n    throw e;\n}","preventionTips":["Verify FTP server disk space and user quota before large writes","Enable passive mode and open the data port range in firewalls","Flush periodically during large uploads to fail fast","Retry full-file writes, never assume a partially transferred file is valid"],"tags":["ftp","network","file-write","data-transfer"],"backgroundTag":"file-write-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}