pentaho/pentaho-kettle · error · IOException

FixedInput.Log.OnlyLocalFilesAreSupported

FixedInput.Log.OnlyLocalFilesAreSupported

Error message

FixedInput.Log.OnlyLocalFilesAreSupported

What it means

The deprecated KettleVFS.getFileInputStream(FileObject) only works on local files because it relies on NIO FileInputStream; if the VFS FileObject is not a commons-vfs LocalFile (e.g. SFTP, HTTP, S3, or a compressed archive entry), it throws an IOException carrying the localized message key FixedInput.Log.OnlyLocalFilesAreSupported.

Solutions

  1. Copy/download the remote file to a local temp path first, then open it locally.
  2. Read the FileObject content generically: fileObject.getContent().getInputStream() instead of the deprecated method.
  3. Use KettleVFS.getInputStream(FileObject) / the non-deprecated API which supports any VFS scheme.
  4. If the file must be local, verify the filename has no scheme or archive prefix.

Example fix

// before
InputStream in = KettleVFS.getFileInputStream(KettleVFS.getFileObject("sftp://host/data.csv", space));
// after
InputStream in = KettleVFS.getInputStream(KettleVFS.getFileObject("sftp://host/data.csv", space));
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(fileObject instanceof org.apache.commons.vfs2.provider.local.LocalFile)) {
  // use generic content input stream instead
}

Type guard

boolean isLocalFile(FileObject fo) { return fo instanceof org.apache.commons.vfs2.provider.local.LocalFile; }

Try / catch

try {
  in = KettleVFS.getFileInputStream(fo);
} catch (IOException e) {
  if (e.getMessage().contains("OnlyLocalFilesAreSupported")) {
    in = fo.getContent().getInputStream(); // generic VFS fallback
  } else throw e;
}

Prevention

When it happens

Trigger: Calling KettleVFS.getFileInputStream on a FileObject obtained from a non-local scheme (sftp://, http://, s3://, zip:..., etc.) — typically via the Fixed Input step or code reading a remote/virtual file with this legacy API.

Common situations: Migrating a transformation that previously read local files to a remote source; pointing the Fixed Input step at an SFTP or HDFS URL; passing an archive entry (zip:file:///x.zip!/inner.csv) where a plain local path was expected.

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/2515df60bc95e1d0. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/vfs/KettleVFS.java:501

    };
  }

  /**
   * Get a FileInputStream for a local file. Local files can be read with NIO.
   *
   * @param fileObject
   * @return a FileInputStream
   * @throws IOException
   * @deprecated because of API change in Apache VFS. As a workaround use FileObject.getName().getPathDecoded(); Then
   * use a regular File() object to create a File Input stream.
   */
  @Deprecated
  public static FileInputStream getFileInputStream( FileObject fileObject ) throws IOException {

    if ( !( fileObject instanceof LocalFile ) ) {
      // We can only use NIO on local files at the moment, so that's what we limit ourselves to.
      //
      throw new IOException( BaseMessages.getString( PKG, "FixedInput.Log.OnlyLocalFilesAreSupported" ) );
    }

    return new FileInputStream( fileObject.getName().getPathDecoded() );
  }

  /**
   * Check if filename starts with one of the known protocols like file: zip: ram: smb: jar: etc.
   * If yes, return true otherwise return false
   *
   * @param vfsFileName
   * @return boolean
   */
  public static boolean startsWithScheme( String vfsFileName ) {
    FileSystemManager fsManager = getInstance().getFileSystemManager();

    boolean found = false;
    String[] schemes = fsManager.getSchemes();
    for (int i = 0; i < schemes.length; i++) {

View on GitHub (pinned to f3058517a1)