{"record":{"id":"65760d090d7c14b8","repo":"apache/hadoop","slug":"could-not-complete-transfer-reply-code","errorCode":null,"errorMessage":"Could not complete transfer, Reply Code - ","messagePattern":"Could not complete transfer, Reply Code - ","errorType":"exception","errorClass":"FTPException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/ftp/FTPInputStream.java","lineNumber":118,"sourceCode":"    return result;\n  }\n\n  @Override\n  public synchronized void close() throws IOException {\n    if (closed) {\n      return;\n    }\n    super.close();\n    closed = true;\n    if (!client.isConnected()) {\n      throw new FTPException(\"Client not connected\");\n    }\n\n    boolean cmdCompleted = client.completePendingCommand();\n    client.logout();\n    client.disconnect();\n    if (!cmdCompleted) {\n      throw new FTPException(\"Could not complete transfer, Reply Code - \"\n          + client.getReplyCode());\n    }\n  }\n\n  // Not supported.\n\n  @Override\n  public boolean markSupported() {\n    return false;\n  }\n\n  @Override\n  public void mark(int readLimit) {\n    // Do nothing\n  }\n\n  @Override\n  public void reset() throws IOException {","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/ftp/FTPInputStream.java#L100-L136","documentation":"In close(), after the data stream ends the client must call completePendingCommand() to read the server's final reply; false means the server never confirmed success (e.g. 4xx/5xx or aborted transfer). The code then logs out, disconnects, and throws FTPException(\"Could not complete transfer, Reply Code - N\"). The reply code is fetched after disconnect(), so treat it as the last known code and verify transfer completeness independently.","triggerScenarios":"Data connection breaking mid-RETR (passive port blocked, NAT timeout); server returning 426/550 during streaming; the reader closing early and abandoning the transfer; local disk/network errors aborting the download.","commonSituations":"Firewalls allowing control port 21 but blocking the passive data port range; large transfers hitting NAT idle timeouts; quota or permission changes on the server mid-session.","solutions":["Match the reply code with the FTP server log entry to find the true 4xx/5xx reason","Verify the passive-mode port range is open end-to-end or switch active/passive mode to suit the network","Validate size after read: compare bytes consumed (getPos()) with the file length from getFileStatus()","Retry the full open/read/close cycle once — transient data-channel failures are common"],"exampleFix":"// before\ntry (FSDataInputStream in = fs.open(path)) {\n  IOUtils.copyBytes(in, out, conf);   // close() may throw \"Could not complete transfer\"\n}\n\n// after\ntry (FSDataInputStream in = fs.open(path)) {\n  IOUtils.copyBytes(in, out, conf);\n  long read = in.getPos();\n  long expected = fs.getFileStatus(path).getLen();\n  if (read != expected) {\n    throw new IOException(\"short read: \" + read + \" of \" + expected);\n  }\n}","handlingStrategy":"retry","validationCode":"// verify completeness before trusting a completed copy\nlong read = in.getPos();\nlong expected = fs.getFileStatus(path).getLen();\nif (read != expected) { /* treat as truncated; plan resume */ }","typeGuard":null,"tryCatchPattern":"catch FTPException from close(); when the message starts with \"Could not complete transfer\", record getPos() as the resume point, reopen the stream, skip to that point, and continue reading — retry the whole cycle once before failing.","preventionTips":["Keep the passive data port range open through every firewall on the path","Always compare consumed bytes with the advertised file length","Capture the server-side reply string in logs for diagnosis"],"tags":["ftp","hadoop","transfer","data-connection","close"],"backgroundTag":"ftp-transfer-incomplete","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}