pentaho/pentaho-kettle · error · FileSystemException
vfs.provider/rename.error
vfs.provider/rename.error
Error message
vfs.provider/rename.error
What it means
Thrown by S3CommonFileObject.doRename() when getObjectMetadata returns null for the source key, meaning the object being renamed does not exist in S3. S3 rename is implemented as copy+delete, and this guard prevents copying a nonexistent source.
Solutions
- Refresh/resolve the FileObject to clear stale cache, then verify the object exists before renaming
- Check the exact key spelling and case in the source URI
- List the bucket/prefix with the S3 console or CLI to confirm the object exists
- Handle the race by re-resolving and retrying, or fail gracefully if the object is already gone
Example fix
// before
FileObject dest = fsManager.resolveFile( "s3://bucket/newname" );
src.rename( dest );
// after
if ( !src.exists() ) {
throw new FileNotFoundException( src.getName().getURI() );
}
src.refresh();
FileObject dest = fsManager.resolveFile( "s3://bucket/newname" );
src.rename( dest ); Defensive patterns
Strategy: validation
Validate before calling
if ( !src.exists() ) {
throw new FileNotFoundException( src.getName().getURI() );
}
src.refresh(); // flush cached metadata
if ( !src.exists() ) {
throw new FileNotFoundException( "stale reference: " + src.getName().getURI() );
} Type guard
boolean existsOnS3( S3CommonFileObject f ) {
return f != null && f.bucketName != null && f.key != null
&& f.fileSystem.getS3Client().doesObjectExist( f.bucketName, f.key );
} Try / catch
try {
src.rename( dest );
} catch ( FileSystemException e ) {
if ( e.getCause() == null && src.getName().equals( e.getInfo()[ 0 ] ) ) {
// source vanished: refresh and re-check before retrying
}
throw e;
} Prevention
- Call refresh() on FileObjects after external S3 modifications
- Re-check existence immediately before rename in concurrent environments
- Verify key spelling/case — S3 keys are case-sensitive
- Enable VFS cache with appropriate TTL or disable caching for rapidly-changing buckets
When it happens
Trigger: Calling rename() on an S3 VFS file whose key was deleted (by another process or a stale cache) between resolution and the rename call.
Common situations: Stale VFS cache pointing at a deleted object; race with a concurrent delete; wrong bucket/key casing (S3 keys are case-sensitive); typo in the source URI.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Could not find folder [ + id + ]
- Exception getting the list of buckets
- File not found
- FileSystemException wrapping KettleFileException
- FileSystemException wrapping SdkClientException
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/afc335a26c970639.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/s3-vfs/core/src/main/java/org/pentaho/s3common/S3CommonFileObject.java:536
protected PutObjectRequest createPutObjectRequest( String bucketName, String key, InputStream inputStream,
ObjectMetadata objectMetadata ) {
return new PutObjectRequest( bucketName, key, inputStream, objectMetadata );
}
@Override
protected void doRename( FileObject newFile ) throws Exception {
// no folder renames on S3
if ( getType().equals( FileType.FOLDER ) ) {
logger.debug( "recursively moving folder [{}] -> [{}]", this.getPublicURIString(), newFile.getPublicURIString() );
doFolderMove( this, newFile );
return;
}
s3ObjectMetadata = fileSystem.getS3Client().getObjectMetadata( bucketName, key );
if ( s3ObjectMetadata == null ) {
// object doesn't exist
throw new FileSystemException( "vfs.provider/rename.error", this, newFile );
}
S3CommonFileObject dest = (S3CommonFileObject) newFile;
// 1. copy the file
CopyObjectRequest copyObjRequest = createCopyObjectRequest( bucketName, key, dest.bucketName, dest.key );
logger.debug( "copyObject ([{}], [{}]) -> ([{}], [{}])", bucketName, key, dest.bucketName, dest.key );
fileSystem.getS3Client().copyObject( copyObjRequest );
// 2. delete self
delete();
}
private void doFolderMove( FileObject sourceFolder, FileObject targetFolder ) throws FileSystemException {
logger.debug( "creating folder [{}]", targetFolder.getPublicURIString() );
FileObject[] children = sourceFolder.getChildren();
targetFolder.createFolder();
for ( FileObject child : children ) {View on GitHub (pinned to f3058517a1)