pentaho/pentaho-kettle · error · KettleException
Only local files are supported at this time, file [
Error message
Only local files are supported at this time, file [
What it means
Thrown by JobEntryMysqlBulkLoad.execute when the configured filename resolves through Kettle VFS to something other than a LocalFile. MySQL LOAD DATA (LOAD DATA LOCAL INFILE) can only read files on the local filesystem, so remote VFS schemes are rejected.
Solutions
- Copy the remote file to the local filesystem first (e.g. with a 'Get a file with FTP/SFTP' step or manual download) and point the entry at the local path.
- Use an absolute local path or file:// URI for the filename field.
- Check any Kettle variables used in the filename resolve to a local path at runtime.
Example fix
// before String filename = "sftp://user@host/data/infile.csv"; // after copyViaSftpToLocal( "sftp://user@host/data/infile.csv", "/tmp/infile.csv" ); String filename = "/tmp/infile.csv";
Defensive patterns
Strategy: validation
Validate before calling
FileObject fo = KettleVFS.getInstance( bowl ).getFileObject( filename );
if ( !( fo instanceof LocalFile ) ) {
throw new IllegalArgumentException( "Copy to local disk first: " + filename );
} Type guard
boolean isLocalFile( FileObject fo ) { return fo instanceof LocalFile; } Try / catch
try {
result = jobEntry.execute( prevResult, nr );
} catch ( KettleException e ) {
if ( e.getMessage().startsWith( "Only local files are supported" ) ) {
// copy remote resource to local temp and retry
}
} Prevention
- Always configure local absolute paths for MySQL bulk-load files.
- Add a pre-step that downloads remote files locally.
- Beware VFS variables resolving to remote schemes.
- Test filename resolution with Spoon before scheduling.
When it happens
Trigger: execute() calls KettleVFS.getFileObject(vfsFilename) and the resolved FileObject is not an instanceof LocalFile — e.g. the filename is an sftp://, http://, hdfs://, s3://, zip: or other non-local VFS URI.
Common situations: User pasted an SFTP or HTTP URL as the bulk-load file; file lives inside a zip/jar accessed via VFS; a cluster/HDFS path used when running a distributed job; variable substitution unexpectedly resolves to a remote scheme.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- ZipFile.Error.NotAFolder
- [ + ArgList[0] + ] is not a folder!
- ConnectionFileSystem.ExpectedConnectionNotFound
- CustomVfsSettingsParser.Log.FailedToLoad
- Error opening new file
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/a106020cf208b219.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/job/entries/mysqlbulkload/JobEntryMysqlBulkLoad.java:272
result.setResult( false );
String vfsFilename = environmentSubstitute( filename );
// Let's check the filename ...
if ( !Utils.isEmpty( vfsFilename ) ) {
try {
// User has specified a file, We can continue ...
//
// This is running over VFS but we need a normal file.
// As such, we're going to verify that it's a local file...
// We're also going to convert VFS FileObject to File
//
FileObject fileObject = KettleVFS.getInstance( parentJobMeta.getBowl() ).getFileObject( vfsFilename, this );
if ( !( fileObject instanceof LocalFile ) ) {
// MySQL LOAD DATA can only use local files, so that's what we limit ourselves to.
//
throw new KettleException( "Only local files are supported at this time, file ["
+ vfsFilename + "] is not a local file." );
}
// Convert it to a regular platform specific file name
//
String realFilename = KettleVFS.getFilename( fileObject );
// Here we go... back to the regular scheduled program...
//
File file = new File( realFilename );
if ( ( file.exists() && file.canRead() ) || isLocalInfile() == false ) {
// User has specified an existing file, We can continue ...
if ( log.isDetailed() ) {
logDetailed( "File [" + realFilename + "] exists." );
}
if ( connection != null ) {
// User has specified a connection, We can continue ...View on GitHub (pinned to f3058517a1)