pentaho/pentaho-kettle · error · SftpException

Failed to rename from to

Error message

Failed to rename from  to 

What it means

MinaSftpSession.rename(oldPath, newPath) wraps IOException from client.rename into an SftpException. The rename failed server-side, typically because the source does not exist, the target already exists (SFTP rename usually refuses overwrite), or permissions are insufficient.

Solutions

  1. Ensure the target does not exist (delete it first) or use a unique temp name for atomic publish
  2. Verify the source path exists and the target's parent directory exists
  3. Check modify permissions on both source and target directories
  4. Retry on transient IO errors after reconnecting the session

Example fix

// before
session.rename("/in/a.csv", "/done/a.csv");
// after
if (session.fileExists("/done/a.csv")) { session.delete("/done/a.csv"); }
session.rename("/in/a.csv", "/done/a.csv");
Defensive patterns

Strategy: validation

Validate before calling

// ensure source exists and target is free before rename
try { session.size(oldPath); } catch (SftpException e) { throw new IllegalStateException("source missing: " + oldPath, e); }
try { session.size(newPath); session.delete(newPath); } catch (SftpException ignored) { /* target absent: fine */ }

Type guard

boolean canRename(MinaSftpSession s, String from, String to) {
  try { s.size(from); return true; } catch (SftpException e) { return false; }
  // plus a target-free check as in validationCode
}

Try / catch

try {
  session.rename(oldPath, newPath);
} catch (SftpException e) {
  if (session.fileExists(newPath)) { session.delete(newPath); session.rename(oldPath, newPath); return; }
  throw new IOException("rename " + oldPath + " -> " + newPath + " failed: " + e.getCause(), e);
}

Prevention

When it happens

Trigger: Calling rename(oldPath, newPath) when oldPath is missing, newPath already exists and the server does not allow overwriting rename, source and target on paths the user cannot modify, or a dropped session.

Common situations: Atomic publish patterns (upload temp then rename) breaking when the destination file was created concurrently, case-only renames on case-insensitive servers, moving files across directories where the target dir is missing.

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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSftpSession.java:142

  @Override
  public void delete( String path ) throws SftpException {
    try {
      if ( isDirectory( path ) ) {
        client.rmdir( path );
      } else {
        client.remove( path );
      }
    } catch ( IOException e ) {
      throw new SftpException( "Failed to delete: " + path, e );
    }
  }

  @Override
  public void rename( String oldPath, String newPath ) throws SftpException {
    try {
      client.rename( oldPath, newPath );
    } catch ( IOException e ) {
      throw new SftpException( "Failed to rename from " + oldPath + " to " + newPath, e );
    }
  }

  @Override
  public void close() {
    try {
      client.close();
    } catch ( IOException ignored ) {
      // Ignore
    }
  }
}

View on GitHub (pinned to f3058517a1)