pentaho/pentaho-kettle · error · KettleException
Error retrieving logfile string
Error message
Error retrieving logfile string
What it means
When meta.getLogFile() is set, createCommandLine() resolves the log file path via environmentSubstitute() and KettleVFS to append '-o <logfile>' to the psql command. Any exception in that resolution is wrapped in this KettleException with the original error as cause. This is a path-resolution wrapper error, not a validation error (a missing log file is optional).
Solutions
- Inspect ex.getCause() for the underlying VFS failure and fix it (missing provider, bad scheme, permissions).
- Make sure every variable in the log path is defined (kettle.properties, transformation parameters, or runtime env).
- Use a plain absolute local path (e.g. /var/log/kettle/gpbulk.log) if VFS complexity is not needed.
- If logging is unnecessary, clear the log file field entirely - the step skips this block when it is null.
Example fix
// before
Log file: ${LOG_DIR}/gpbulk.log (LOG_DIR undefined)
// after
kettle.properties: LOG_DIR=/var/log/kettle
Log file: ${LOG_DIR}/gpbulk.log Defensive patterns
Strategy: validation
Validate before calling
String log = meta.getLogFile();
if (log != null && !log.trim().isEmpty()) {
String resolved = transformation.environmentSubstitute(log);
if (resolved.contains("${"))
throw new IllegalArgumentException("Unresolved variable in log path: " + log);
java.io.File dir = new java.io.File(resolved).getParentFile();
if (dir != null && !dir.canWrite())
throw new IllegalArgumentException("Log dir not writable: " + dir);
} Try / catch
try {
execute(meta, wait);
} catch (KettleException e) {
if (e.getMessage().contains("Error retrieving logfile string")) {
logError("Log file path resolution failed, continuing without log", e.getCause());
meta.setLogFile(null); // log file is optional; retry without it
execute(meta, wait);
} else throw e;
} Prevention
- Leave the log file field empty if file logging is not needed - it is optional
- Point the log at a plain local directory with write permission for the Kettle user
- Define any variable used in the log path in kettle.properties
When it happens
Trigger: createCommandLine() runs with meta.getLogFile() non-null and KettleVFS.getFileObject(environmentSubstitute(logFile)) throws: unsupported VFS scheme, invalid path, IO failure, or unresolvable ${VAR} inside the log file path.
Common situations: Log path uses a variable undefined at runtime; log directory on a network share not mounted or not covered by a VFS provider; filename contains characters VFS rejects; path points to a scheme like s3:// unsupported by the installed VFS plugins.
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
- Error retrieving controlfile string
- Error retrieving sqlldr string
- [ + ArgList[0] + ] is not a file!
- AvroInputDialog.Error.KettleFileException
- ChangeFileEncoding.Error.ParentFolderNotExist
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/8e5497da15ba8711.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/gp-bulk-loader/core/src/main/java/org/pentaho/di/trans/steps/gpbulkloader/GPBulkLoader.java:349
sb.append( " -n -f " );
sb.append( enclosure ).append( KettleVFS.getFilename( fileObject ) ).append( enclosure );
} catch ( Exception ex ) {
throw new KettleException( "Error retrieving controlfile string", ex );
}
} else {
throw new KettleException( "No control file specified" );
}
if ( meta.getLogFile() != null ) {
try {
FileObject fileObject =
KettleVFS.getInstance( getTransMeta().getBowl() )
.getFileObject( environmentSubstitute( meta.getLogFile() ), getTransMeta() );
sb.append( " -o " );
sb.append( enclosure ).append( KettleVFS.getFilename( fileObject ) ).append( enclosure );
} catch ( Exception ex ) {
throw new KettleException( "Error retrieving logfile string", ex );
}
}
DatabaseMeta dm = meta.getDatabaseMeta();
if ( dm != null ) {
String user = Const.NVL( dm.getUsername(), "" );
// Passwords will not work for now because we can't get them to the command line without assuming UNIX and using
// an environment variable
String pass = Const.NVL( dm.getPassword(), "" );
if ( password && !pass.equalsIgnoreCase( "" ) ) {
throw new KettleException(
"Passwords are not supported directly, try configuring "
+ "your connection for trusted access using pg_hba.conf" );
}
// if ( ! password )
// {
// pass = "******";View on GitHub (pinned to f3058517a1)