{"record":{"id":"36d88620621ccd69","repo":"pentaho/pentaho-kettle","slug":"vfs-provider-create-file-error-36d886","errorCode":"vfs.provider/create-file.error","errorMessage":"vfs.provider/create-file.error","messagePattern":"vfs\\.provider/create-file\\.error","errorType":"error_code","errorClass":"FileSystemException","httpStatus":null,"severity":"error","filePath":"plugins/s3-vfs/core/src/main/java/org/pentaho/s3common/S3CommonFileObject.java","lineNumber":94,"sourceCode":"    return new S3CommonFileInputStream( streamS3Object.getObjectContent(), streamS3Object );\n  }\n\n  @Override\n  public Path getPath() {\n    // default impl will only work for schemes registered with nio\n    String namePath = getName().getPath();\n    String[] pathElements = StringUtils.split( namePath, DELIMITER );\n    return Path.of( \"\", pathElements );\n  }\n\n  @Override public void createFile() throws FileSystemException {\n    //PDI-19598: Copied from super.createFile() but it was a way to force the file creation on S3\n    synchronized ( fileSystem ) {\n      try {\n        // VFS-210: We do not want to trunc any existing file, checking for its existence is\n        // still required\n        if ( exists() && !isFile() ) {\n          throw new FileSystemException( \"vfs.provider/create-file.error\", super.getName() );\n        }\n\n        if ( !exists() ) {\n          try ( OutputStream outputStream = getOutputStream() ) {\n            //Force to write an empty array to force file creation on S3 bucket\n            outputStream.write( new byte[] {} );\n          }\n          endOutput();\n        }\n      } catch ( final RuntimeException re ) {\n        throw re;\n      } catch ( final Exception e ) {\n        throw new FileSystemException( \"vfs.provider/create-file.error\", super.getName(), e );\n      }\n    }\n  }\n\n  @Override","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/s3-vfs/core/src/main/java/org/pentaho/s3common/S3CommonFileObject.java#L76-L112","documentation":"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.","triggerScenarios":"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 '/').","commonSituations":"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.","solutions":["Choose a different target key that does not collide with an existing folder prefix.","Delete the folder placeholder object in S3 before creating the file.","Check exists() && isFile() before calling createFile() and handle the collision explicitly.","Use folder delimiter conventions consistently in your pipeline paths."],"exampleFix":"// before\nfileObject.createFile();\n// after\nif ( fileObject.exists() && !fileObject.isFile() ) {\n  throw new IOException( \"Target exists as a folder in S3: \" + fileObject.getName() );\n}\nfileObject.createFile();","handlingStrategy":"validation","validationCode":"if ( fileObject.exists() ) {\n  if ( !fileObject.isFile() ) {\n    throw new IllegalStateException( \"S3 target is a folder, not a file: \" + fileObject.getName() );\n  }\n}\n// safe to createFile() now","typeGuard":null,"tryCatchPattern":"try {\n  fileObject.createFile();\n} catch ( FileSystemException e ) {\n  if ( fileObject.exists() && fileObject.getType() != FileType.FILE ) {\n    // collision with an S3 folder placeholder — pick a new key\n  }\n  throw e;\n}","preventionTips":["Never name files the same as existing folder prefixes in a bucket","Enforce a single convention for keys (either with or without trailing slashes)","Enumerate prefixes before bulk writes to detect collisions","Use separate bucket/prefixes for folder-like vs file-like data"],"tags":["s3","vfs","file-create","key-collision"],"backgroundTag":"file-already-exists","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}