pentaho/pentaho-kettle · error · IOException

unable to create directory:

Error message

unable to create directory: 

What it means

CustomDataStoreFactory's constructor calls dataDirectory.mkdirs() when the directory does not exist; if mkdirs() returns false the factory throws IOException 'unable to create directory: <dir>'. This typically means a filesystem-level failure creating the local cache directory.

Solutions

  1. Check the parent directory's write permissions for the process user and fix with chown/chmod.
  2. Verify no regular file exists at that path; remove or rename it so the directory can be created.
  3. Ensure the filesystem/volume is writable (not mounted read-only).
  4. Create the directory manually beforehand with correct ownership.

Example fix

// before
new CustomDataStoreFactory(new File("/readonly/mnt/drive-cache")); // mkdirs fails
// after
new CustomDataStoreFactory(new File("/var/lib/app/drive-cache")); // writable path
Defensive patterns

Strategy: validation

Validate before calling

File dir = new File(path);
if (!dir.isDirectory()) {
  boolean created = dir.mkdirs();
  if (!created) {
    throw new IllegalStateException("cannot create data dir (permissions? read-only fs?): " + path);
  }
}

Try / catch

try {
  new CustomDataStoreFactory(dataDirectory);
} catch (IOException e) {
  if (e.getMessage().startsWith("unable to create directory")) {
    // fix permissions / writable path, then retry once
  } else { throw e; }
}

Prevention

When it happens

Trigger: Constructing new CustomDataStoreFactory(dataDirectory) where the directory does not exist and mkdirs() fails — parent directory missing with no create permission, read-only filesystem, or a non-directory file already occupying the path.

Common situations: Running as a user without write permission on the parent folder; read-only container volumes; a regular file existing where the directory should be; SELinux/AppArmor denials.

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

Appendix: source

Thrown at plugins/pentaho-googledrive-vfs/core/src/main/java/org/pentaho/googledrive/vfs/util/CustomDataStoreFactory.java:50

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.HashMap;
import java.util.List;
import java.util.Iterator;

public class CustomDataStoreFactory extends AbstractDataStoreFactory {

  private final File dataDirectory;

  public CustomDataStoreFactory( File dataDirectory ) throws IOException {
    dataDirectory = dataDirectory.getCanonicalFile();
    this.dataDirectory = dataDirectory;
    if ( IOUtils.isSymbolicLink( dataDirectory ) ) {
      throw new IOException( "unable to use a symbolic link: " + dataDirectory );
    } else if ( !dataDirectory.exists() && !dataDirectory.mkdirs() ) {
      throw new IOException( "unable to create directory: " + dataDirectory );
    }
  }

  protected <V extends Serializable> DataStore<V> createDataStore( String id ) throws IOException {
    return new CustomDataStore( this, this.dataDirectory, id );
  }

  static class CustomDataStore<V extends Serializable> extends AbstractDataStore<V> {
    private File dataFile = null;
    private File dataDirectory = null;
    private HashMap<String, byte[]> keyValueMap = Maps.newHashMap();
    private final Lock lock = new ReentrantLock();

    CustomDataStore( CustomDataStoreFactory dataStore, File dataDirectory, String id ) throws IOException {
      super( dataStore, id );
      this.dataDirectory = dataDirectory;
      this.dataFile = new File( this.dataDirectory, getId() );

View on GitHub (pinned to f3058517a1)