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

  1. 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.
  2. Use an absolute local path or file:// URI for the filename field.
  3. 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

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


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)