pentaho/pentaho-kettle · error · SftpException

Failed to create directory:

Error message

Failed to create directory: 

What it means

MinaSftpSession.mkdir() wraps IOException from client.mkdir(path) into an SftpException. The remote directory could not be created, usually because the parent directory is missing or the user lacks write permission. The server-side SSH_FXP_STATUS code is in the cause.

Solutions

  1. Create parent directories one level at a time (or add a recursive mkdir helper) before creating the leaf
  2. Check write permission for the SSH user on the parent directory
  3. Ignore or pre-check the case where the directory already exists
  4. Read e.getCause() to distinguish permission-denied from no-such-file

Example fix

// before
session.mkdir("/data/2026/09/uploads");
// after
String[] parts = "/data/2026/09/uploads".split("/");
String cur = "";
for (String p : parts) {
  if (p.isEmpty()) { cur = "/"; continue; }
  cur = cur.endsWith("/") ? cur + p : cur + "/" + p;
  try { session.mkdir(cur); } catch (SftpException e) { /* already exists - continue */ }
}
Defensive patterns

Strategy: validation

Validate before calling

// recursive pre-creation so parent is never missing
String cur = "";
for (String part : path.split("/")) {
  if (part.isEmpty()) { cur = "/"; continue; }
  cur = (cur.equals("/") ? "" : cur) + "/" + part;
  try { session.mkdir(cur); } catch (SftpException alreadyExists) { /* continue */ }
}

Type guard

boolean canMkdir(MinaSftpSession s, String parent) {
  try { s.mkdir(parent + "/.probe"); s.delete(parent + "/.probe"); return true; }
  catch (SftpException e) { return false; }
}

Try / catch

try {
  session.mkdir(path);
} catch (SftpException e) {
  if (session.fileExists(path)) { /* treat as success */ return; }
  throw new IOException("mkdir failed for " + path + ": " + e.getCause(), e);
}

Prevention

When it happens

Trigger: Calling mkdir(path) when the parent directory does not exist (SFTP mkdir is not recursive), the SSH user lacks write permission on the parent, or the directory already exists and the server rejects it.

Common situations: Creating deep paths like /data/2026/09/uploads in one call when /data/2026 does not exist, deploying pipelines that assume a service account has write access it does not, or a chrooted user trying paths outside their root.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


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

Appendix: source

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

        while ( ( r = source.read( buf ) ) >= 0 ) {
          if ( r == 0 ) {
            continue;
          }
          client.write( h, off, buf, 0, r );
          off += r;
        }
      }
    } catch ( IOException e ) {
      throw new SftpException( "Failed to upload file: " + remote, e );
    }
  }

  @Override
  public void mkdir( String path ) throws SftpException {
    try {
      client.mkdir( path );
    } catch ( IOException e ) {
      throw new SftpException( "Failed to create directory: " + path, e );
    }
  }

  @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 {

View on GitHub (pinned to f3058517a1)