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
- Check the parent directory's write permissions for the process user and fix with chown/chmod.
- Verify no regular file exists at that path; remove or rename it so the directory can be created.
- Ensure the filesystem/volume is writable (not mounted read-only).
- 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
- Pre-create the data directory with correct ownership in deployment scripts.
- Check parent directory write permissions for the service user.
- Ensure volumes are mounted read-write; verify no file occupies the directory path.
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
- unable to use a symbolic link:
- Error opening new file
- FixedInput.Log.OnlyLocalFilesAreSupported
- IO exception while running the process
- IOError while create
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)