pentaho/pentaho-kettle · error · KettleStepException
SFTPPut.Error.CanNotFindField
Error message
SFTPPut.Error.CanNotFindField
What it means
Thrown when the source file path resolved from the row does not exist on the local/VFS filesystem. SFTPPut resolves the path via KettleVFS and calls file.exists(); if false it aborts the row with this KettleStepException, including the path in the message. It prevents attempting to open a stream on a non-existent file.
Solutions
- Check the path in the error message and confirm the file exists at that exact location at run time.
- Fix variables/relative paths (e.g. use ${Internal.Transformation.Filename.Directory}) so the absolute path is correct.
- Ensure the upstream step that writes the file completes before SFTPPut runs (proper hop ordering).
- Add an upstream 'Check if file exists' / Filter step to handle missing files gracefully.
Example fix
// before
String path = "/data/${TODAY}/export.csv"; // variable not substituted
// after
String path = environmentSubstitute("${DATA_DIR}/export.csv"); // resolves to existing file Defensive patterns
Strategy: validation
Validate before calling
File f = new File(environmentSubstitute(sourcePath));
if (f == null || !f.exists()) {
throw new FileNotFoundException("Source file missing before SFTPPut: " + sourcePath);
} Try / catch
try {
transform.execute();
} catch (KettleStepException e) {
if (e.getMessage().contains("CanNotFindField") && e.getMessage().contains(path)) {
log.error("Source file does not exist: " + path);
// route row to an error/retry path
} else { throw e; }
} Prevention
- Use absolute, variable-substituted paths (${Internal.Transformation.Filename.Directory}).
- Ensure the producing step finishes before SFTPPut (correct hop order).
- Check file existence in a prior step and branch on the result.
- Verify files are not removed by cleanup jobs between steps.
When it happens
Trigger: processRow reads sourceData (a file path string) from the row, KettleVFS.getFileObject(sourceData) succeeds but file.exists() returns false.
Common situations: Upstream step generated a filename that was never written; wrong working directory or relative path; file deleted or moved between steps; variable/environment substitution resolving to an unexpected location; permission issues making existence checks fail.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- SFTPPut.Error.CanNotFindFolder
- ChangeFileEncoding.Error.SourceFileNotExists
- CsvInput.Log.OnlyLocalFilesAreSupported
- Error retrieving command string
- file [ + ArgList[0] + ] can not be found!
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/1e3f914d00dcd11c.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/sftpput/impl/src/main/java/org/pentaho/di/trans/steps/sftpput/SFTPPut.java:179
if ( meta.isInputStream() ) {
// Source data is a stream
inputStream = new ByteArrayInputStream( getInputRowMeta().getBinary( r, data.indexOfSourceFileFieldName ) );
if ( data.indexOfRemoteFilename == -1 ) {
// for the case when put data is transferred via input field
// it is mandatory to specify remote file name
throw new KettleStepException( BaseMessages.getString( PKG, "SFTPPut.Error.RemoteFilenameFieldMissing" ) );
}
destinationFilename = getInputRowMeta().getString( r, data.indexOfRemoteFilename );
} else {
// source data is a file
// let's check file
file = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( sourceData );
if ( !file.exists() ) {
// We can not find file
throw new KettleStepException( BaseMessages.getString( PKG, "SFTPPut.Error.CanNotFindField", sourceData ) );
}
// get stream from file
inputStream = KettleVFS.getInputStream( file );
// 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" ) );
}
View on GitHub (pinned to f3058517a1)