pentaho/pentaho-kettle · error · KettleException
Error retrieving controlfile string
Error message
Error retrieving controlfile string
What it means
After appending the psql executable, createCommandLine() resolves meta.getControlFile() through environmentSubstitute() and KettleVFS to append '-n -f <controlfile>' to the psql command. Any exception during that resolution is wrapped in this KettleException. The real cause (VFS error, bad path, unresolved variable) is attached as the cause.
Solutions
- Check ex.getCause() to see the actual VFS/resolution error and fix that root problem.
- Resolve all variables in the control file path (define them in kettle.properties or as transformation parameters).
- Verify the control file exists at the given path on the machine running Kettle (not just where psql will run).
- Use forward slashes / a supported VFS URI (file:///...) if the path contains Windows backslashes.
Example fix
// before
Control file: ${GP_CTL}/load.ctl (GP_CTL undefined -> VFS/variable resolution throws)
// after: define the variable or hardcode a verified path
kettle.properties: GP_CTL=/opt/gp/control
Control file: ${GP_CTL}/load.ctl Defensive patterns
Strategy: validation
Validate before calling
String ctl = meta.getControlFile();
if (ctl == null || ctl.trim().isEmpty())
throw new IllegalArgumentException("Control file not set");
String resolved = transformation.environmentSubstitute(ctl);
if (resolved.contains("${"))
throw new IllegalArgumentException("Unresolved variable in control file path: " + ctl);
if (!new java.io.File(resolved).canRead())
throw new IllegalArgumentException("Control file not readable: " + resolved); Try / catch
try {
execute(meta, wait);
} catch (KettleException e) {
if (e.getMessage().contains("Error retrieving controlfile string")) {
logError("Control file resolution failed", e.getCause());
} else throw e;
} Prevention
- Verify the control file exists on the Kettle host before running
- Resolve variables at the transformation parameter level, not ad hoc
- Use forward-slash paths to avoid VFS backslash issues on Windows
When it happens
Trigger: createCommandLine() runs with meta.getControlFile() non-null, but KettleVFS.getFileObject(environmentSubstitute(controlFile)) throws: unknown VFS scheme, IO error resolving the file, or an unresolvable variable inside the control file path.
Common situations: Control file path references a variable not defined in kettle.properties or transformation parameters; control file lives on a remote VFS mount whose provider is missing; the control file was deleted/moved after the transformation was saved; Windows path with backslashes misinterpreted by VFS.
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 logfile 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/2b62cdc5afe01dcf.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/gp-bulk-loader/core/src/main/java/org/pentaho/di/trans/steps/gpbulkloader/GPBulkLoader.java:334
String psqlexec = KettleVFS.getFilename( fileObject );
sb.append( enclosure ).append( psqlexec ).append( enclosure );
} catch ( Exception ex ) {
throw new KettleException( "Error retrieving sqlldr string", ex );
}
} else {
throw new KettleException( "No psql application specified" );
}
if ( meta.getControlFile() != null ) {
try {
FileObject fileObject =
KettleVFS.getInstance( getTransMeta().getBowl() )
.getFileObject( environmentSubstitute( meta.getControlFile() ), getTransMeta() );
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 );
}
}
View on GitHub (pinned to f3058517a1)