pentaho/pentaho-kettle · error · FileSystemException

vfs.provider/create-file.error

vfs.provider/create-file.error

Error message

vfs.provider/create-file.error

What it means

S3CommonFileObject.createFile() (PDI-19598 override of the VFS default) refuses to create a file if the target exists in S3 but is not a regular file (e.g. it is a folder/prefix). It throws FileSystemException('vfs.provider/create-file.error', name) without a cause — the invariant 'existing object must be a file' was violated.

Solutions

  1. Choose a different target key that does not collide with an existing folder prefix.
  2. Delete the folder placeholder object in S3 before creating the file.
  3. Check exists() && isFile() before calling createFile() and handle the collision explicitly.
  4. Use folder delimiter conventions consistently in your pipeline paths.

Example fix

// before
fileObject.createFile();
// after
if ( fileObject.exists() && !fileObject.isFile() ) {
  throw new IOException( "Target exists as a folder in S3: " + fileObject.getName() );
}
fileObject.createFile();
Defensive patterns

Strategy: validation

Validate before calling

if ( fileObject.exists() ) {
  if ( !fileObject.isFile() ) {
    throw new IllegalStateException( "S3 target is a folder, not a file: " + fileObject.getName() );
  }
}
// safe to createFile() now

Try / catch

try {
  fileObject.createFile();
} catch ( FileSystemException e ) {
  if ( fileObject.exists() && fileObject.getType() != FileType.FILE ) {
    // collision with an S3 folder placeholder — pick a new key
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling createFile() (e.g. via fileObject.createFile() or resolving then writing) on an S3 key that already exists as a folder/directory object (zero-byte key ending with '/').

Common situations: Overwriting an S3 'folder' with a file of the same name, VFS path resolving to a prefix created by the S3 console, or conflicting naming conventions between prefix-style keys and files.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/36d88620621ccd69. Report an issue: GitHub.

Appendix: source

Thrown at plugins/s3-vfs/core/src/main/java/org/pentaho/s3common/S3CommonFileObject.java:94

    return new S3CommonFileInputStream( streamS3Object.getObjectContent(), streamS3Object );
  }

  @Override
  public Path getPath() {
    // default impl will only work for schemes registered with nio
    String namePath = getName().getPath();
    String[] pathElements = StringUtils.split( namePath, DELIMITER );
    return Path.of( "", pathElements );
  }

  @Override public void createFile() throws FileSystemException {
    //PDI-19598: Copied from super.createFile() but it was a way to force the file creation on S3
    synchronized ( fileSystem ) {
      try {
        // VFS-210: We do not want to trunc any existing file, checking for its existence is
        // still required
        if ( exists() && !isFile() ) {
          throw new FileSystemException( "vfs.provider/create-file.error", super.getName() );
        }

        if ( !exists() ) {
          try ( OutputStream outputStream = getOutputStream() ) {
            //Force to write an empty array to force file creation on S3 bucket
            outputStream.write( new byte[] {} );
          }
          endOutput();
        }
      } catch ( final RuntimeException re ) {
        throw re;
      } catch ( final Exception e ) {
        throw new FileSystemException( "vfs.provider/create-file.error", super.getName(), e );
      }
    }
  }

  @Override

View on GitHub (pinned to f3058517a1)