pentaho/pentaho-kettle · error · KettleStepException
SFTPPut.Error.CanNotFindFolder
Error message
SFTPPut.Error.CanNotFindFolder
What it means
Thrown when the move-to destination folder (after-FTP move action) does not exist. The step resolves the folder via KettleVFS and calls exists(); if false it aborts with KettleStepException including the folder path. The step does not create missing destination folders.
Solutions
- Create the destination folder before running the transformation, or add a step that creates it.
- Correct the folder path in the row data or configuration; use environment-substituted absolute paths.
- Verify the VFS URI/scheme and credentials for remote folders.
- Add an upstream existence check or 'Create a folder' step for robustness.
Example fix
// before
String folder = "/archive/2026/09"; // never created
// after (upstream step or script)
Files.createDirectories(Paths.get("/archive/2026/09")); Defensive patterns
Strategy: validation
Validate before calling
Path dir = Paths.get(environmentSubstitute(moveToFolder));
if (!Files.isDirectory(dir)) {
Files.createDirectories(dir); // or fail fast before the transformation runs
} Try / catch
try {
transform.execute();
} catch (KettleStepException e) {
if (e.getMessage().contains("CanNotFindFolder")) {
log.error("Create the archive folder or fix the path: " + extractPath(e.getMessage()));
} else { throw e; }
} Prevention
- Pre-create destination folders in deployment scripts.
- Use absolute paths with environment variables for cross-environment correctness.
- Verify VFS URI scheme and credentials for remote folders.
- Add an upstream 'Create a folder' step.
When it happens
Trigger: After-FTP action is MOVE, the folder string from the row is non-empty, but KettleVFS destinationFolder.exists() returns false (typo, missing directory, wrong protocol/URI, or unreachable network share).
Common situations: Typo in the archive folder path; directory not pre-created on a new environment; VFS URI scheme mismatch (e.g. sftp:// vs file://); relative path resolving against an unexpected base directory; mounted drive unavailable.
Related errors
- SFTPPut.Error.CanNotFindField
- CsvInput.Log.OnlyLocalFilesAreSupported
- LoadFileInput.Error.GettingFileContent
- SFTPPut.Error.MoveToDestinationFolderIsEmpty
- SFTPPut.Error.RemoteFilenameFieldMissing
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/c789d4c0628768fd.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/sftpput/impl/src/main/java/org/pentaho/di/trans/steps/sftpput/SFTPPut.java:202
// Destination filename
destinationFilename = file.getName().getBaseName();
}
if ( file != null ) {
if ( meta.getAfterFTPS() == JobEntrySFTPPUT.AFTER_FTPSPUT_MOVE ) {
String realDestationFolder = getInputRowMeta().getString( r, data.indexOfMoveToFolderFieldName );
if ( Utils.isEmpty( realDestationFolder ) ) {
// Move to destination folder is empty
throw new KettleStepException( BaseMessages.getString(
PKG, "SFTPPut.Error.MoveToDestinationFolderIsEmpty" ) );
}
destinationFolder = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( realDestationFolder );
if ( !destinationFolder.exists() ) {
// We can not find folder
throw new KettleStepException( BaseMessages.getString(
PKG, "SFTPPut.Error.CanNotFindFolder", realDestationFolder ) );
}
}
}
// move to spool dir ...
setSFTPDirectory( getInputRowMeta().getString( r, data.indexOfRemoteDirectory ) );
// Upload a stream
data.sftpclient.put( inputStream, destinationFilename );
if ( file != null ) {
// We successfully uploaded the file
// what's next ...
finishTheJob( file, sourceData, destinationFolder );
}
putRow( getInputRowMeta(), r ); // copy row to possible alternate rowset(s).View on GitHub (pinned to f3058517a1)