pentaho/pentaho-kettle · error · KettleException
We can not find file []!
Error message
We can not find file []!
What it means
Database.execStatementsFromFile() (execSqlFile path) throws this when the SQL script file resolved via KettleVFS does not exist on the filesystem/VFS layer. It is thrown after the filename emptiness check, so the name was provided but nothing exists at that path. The library deliberately fails fast instead of proceeding to open an input stream.
Solutions
- Verify the file exists at the exact resolved path (ls/cat or VFS listing) before running the transformation.
- Convert relative paths to absolute, ideally using kettle environment variables like ${Internal.Job.Filename.Directory} to build the path.
- Check for typos, case sensitivity, and Windows vs Unix path separators.
- Ensure the file is deployed to every execution node when running clustered.
- If the file is intentionally optional, check existence (KettleVFS.getFileObject(f).exists()) before invoking.
Example fix
// before
database.execStatementsFromFile(logChannel, sqlFilePath, false, true, null, charset);
// after
FileObject f = KettleVFS.getInstance(bowl).getFileObject(sqlFilePath);
if (f == null || !f.exists()) { throw new IllegalStateException("SQL file missing: " + sqlFilePath); }
database.execStatementsFromFile(logChannel, sqlFilePath, false, true, null, charset); Defensive patterns
Strategy: validation
Validate before calling
FileObject f = KettleVFS.getInstance(bowl).getFileObject(sqlFilePath);
if (Utils.isEmpty(sqlFilePath) || f == null || !f.exists()) {
throw new IllegalArgumentException("SQL file not found: " + sqlFilePath);
} Type guard
boolean sqlFileExists(String path) {
try { FileObject f = KettleVFS.getInstance(new Bowl()).getFileObject(path); return f != null && f.exists(); }
catch (Exception e) { return false; }
} Try / catch
try {
database.execStatementsFromFile(logChannel, path, false, true, null, charset);
} catch (KettleException e) {
if (e.getMessage() != null && e.getMessage().startsWith("We can not find file")) {
// resolve absolute path, check deployment, retry once with corrected path
} else { throw e; }
} Prevention
- Resolve relative paths against ${Internal.Job.Filename.Directory} before use.
- Check file existence on every execution node in clustered setups.
- Avoid hand-built paths with mixed separators; use VFS URIs.
When it happens
Trigger: Calling Database.execStatementsFromFile (or SQL execution from file) with a filename that is non-empty but points to a missing file — wrong absolute path, file deleted before execution, or VFS scheme/URI resolution pointing elsewhere.
Common situations: Job/transformation configuration references an .sql file relative to a working directory that differs at runtime; file lives in a repo but not on the execution node; path uses Windows-style separators or unexpanded variables like ${Internal.Job.Filename.Directory}.
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
- [ + ArgList[0] + ] is not a folder!
- ExcelInput.Exception.CanNotCreateFileObject
- File not found
- folder [ + ArgList[0] + ] can not be found!
- Xslt.Exception.ErrorXSLFileNotExists
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/3865fbee5132da59.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:5294
* Execute an SQL statement inside a file on the database connection (has to be open)
*
* @param filename The file that contains SQL to execute
* @return a Result object indicating the number of lines read, deleted, inserted, updated, ...
* @throws KettleDatabaseException in case anything goes wrong.
* @sendSinglestatement send one statement
*/
public Result execStatementsFromFile( Bowl bowl, String filename, boolean sendSinglestatement )
throws KettleException {
FileObject sqlFile = null;
InputStream is = null;
InputStreamReader bis = null;
try {
if ( Utils.isEmpty( filename ) ) {
throw new KettleException( "Filename is missing!" );
}
sqlFile = KettleVFS.getInstance( bowl ).getFileObject( filename );
if ( !sqlFile.exists() ) {
throw new KettleException( "We can not find file [" + filename + "]!" );
}
is = KettleVFS.getInputStream( sqlFile );
bis = new InputStreamReader( new BufferedInputStream( is, 500 ) );
BufferedReader buff = new BufferedReader( bis );
String sLine;
StringBuilder sql = new StringBuilder( Const.CR );
while ( ( sLine = buff.readLine() ) != null ) {
if ( Utils.isEmpty( sLine ) ) {
sql.append( Const.CR );
} else {
sql.append( Const.CR ).append( sLine );
}
}
if ( sendSinglestatement ) {View on GitHub (pinned to f3058517a1)