{"record":{"id":"78811dd98ffa1eb1","repo":"pentaho/pentaho-kettle","slug":"jobftps-error-deletingfile","errorCode":"JobFTPS.Error.DeletingFile","errorMessage":"JobFTPS.Error.DeletingFile","messagePattern":"JobFTPS\\.Error\\.DeletingFile","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/ftps/impl/src/main/java/org/pentaho/di/job/entries/ftpsget/FTPSConnection.java","lineNumber":521,"sourceCode":"    } catch ( Exception e ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"JobFTPS.Error.RetrievingFilenames\" ), e );\n    }\n    return list == null ? null : list.toArray( new String[list.size()] );\n  }\n\n  /**\n   *\n   * this method is used to delete a file in remote host\n   *\n   * @param file\n   *          File on remote host to delete\n   * @throws KettleException\n   */\n  public void deleteFile( FTPFile file ) throws KettleException {\n    try {\n      this.connection.deleteFile( file );\n    } catch ( Exception e ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"JobFTPS.Error.DeletingFile\", file.getName() ), e );\n    }\n  }\n\n  /**\n   *\n   * this method is used to delete a file in remote host\n   *\n   * @param filename\n   *          Name of file on remote host to delete\n   * @throws KettleException\n   */\n  public void deleteFile( String filename ) throws KettleException {\n    try {\n      this.connection.deleteFile( new FTPFile( getWorkingDirectory(), filename ) );\n    } catch ( Exception e ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"JobFTPS.Error.DeletingFile\", filename ), e );\n    }\n  }","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/ftps/impl/src/main/java/org/pentaho/di/job/entries/ftpsget/FTPSConnection.java#L503-L539","documentation":"FTP client failure in FTPSConnection.deleteFile (called from downloadFiles): the remote file could not be deleted after processing. The localized message includes the filename and chains the underlying FTP error, typically a permission problem or the file already being gone.","triggerScenarios":"downloadFiles -> deleteFile(FTPFile) after transfer when the server rejects DELE — file already gone, permission denied, or connection lost","commonSituations":"another process removed the file between listing and delete; FTPS user lacks delete permission; race with files being consumed by multiple job instances","solutions":["Check the FTPS user has DELETE permission on the remote folder","Guard against races: only delete files you just downloaded and handle 'file not found' as benign","Re-list the directory to confirm the file still exists before deleting","Verify connection health; reconnect and retry if the control channel dropped"],"exampleFix":"// before\nconnection.deleteFile(ftpFile); // fails if already deleted\n// after\ntry {\n  connection.deleteFile(ftpFile);\n} catch (KettleException e) {\n  logBasic(\"File already removed, skipping: \" + ftpFile.getName());\n}","handlingStrategy":"try-catch","validationCode":"boolean stillThere = Arrays.stream(connection.getFileNames(remoteDir, null))\n  .anyMatch(n -> n.equals(file.getName()));","typeGuard":null,"tryCatchPattern":"try {\n  connection.deleteFile(ftpFile);\n} catch (KettleException e) {\n  logBasic(\"Delete after download failed (possibly already removed): \" + ftpFile.getName());\n}","preventionTips":["Treat not-found on post-download delete as benign","Grant delete permission to the FTPS user","Run a single job instance to avoid concurrent consumption races"],"tags":["ftps","file-delete"],"backgroundTag":"permission-denied","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}