prestodb/presto · error · IOException

Configured staging path is not a directory:

Error message

Configured staging path is not a directory: 

What it means

create() validates the configured staging directory (where multipart-upload temp files are buffered locally) and throws if it exists but is not a directory. The hive.s3.staging-directory setting points at a regular file or an invalid filesystem entry.

Source

Thrown at presto-hive/src/main/java/com/facebook/presto/hive/s3/PrestoS3FileSystem.java:440

        return new FSDataInputStream(
                new BufferedFSInputStream(
                        new PrestoS3InputStream(s3, getBucketName(uri), path, maxAttempts, maxBackoffTime, maxRetryTime),
                        bufferSize));
    }

    @Override
    public FSDataOutputStream create(Path path, FsPermission permission, boolean overwrite, int bufferSize, short replication, long blockSize, Progressable progress)
            throws IOException
    {
        if ((!overwrite) && exists(path)) {
            throw new IOException("File already exists:" + path);
        }

        if (!stagingDirectory.exists()) {
            createDirectories(stagingDirectory.toPath());
        }
        if (!stagingDirectory.isDirectory()) {
            throw new IOException("Configured staging path is not a directory: " + stagingDirectory);
        }
        File tempFile = createTempFile(stagingDirectory.toPath(), "presto-s3-", ".tmp").toFile();

        String key = keyFromPath(qualifiedPath(path));
        return new FSDataOutputStream(
                new PrestoS3OutputStream(s3,
                        getBucketName(uri),
                        key,
                        tempFile,
                        sseEnabled,
                        sseType,
                        sseKmsKeyId,
                        multiPartUploadMinFileSize,
                        multiPartUploadMinPartSize,
                        s3AclType,
                        s3StorageClass),
                statistics);
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Fix the staging-directory config to point to a real directory (e.g. /tmp/presto-s3-staging).
  2. Remove or rename the offending file at that path and let Presto recreate the directory.
  3. Ensure the Presto process user has write permission on the staging parent.
  4. Re-check after container/volume changes that the mount is a directory.

Example fix

// before (properties)
hive.s3.staging-directory=/etc/presto/s3-staging.cfg   // a file
// after
hive.s3.staging-directory=/tmp/presto-s3-staging
Defensive patterns

Strategy: validation

Validate before calling

java.io.File staging = new java.io.File(config.get("hive.s3.staging-directory"));
if (staging.exists() && !staging.isDirectory()) {
    throw new IllegalStateException("staging path is a file: " + staging);
}
if (!staging.exists() && !staging.mkdirs()) {
    throw new IllegalStateException("cannot create staging dir: " + staging);
}

Type guard

boolean isUsableStagingDir(java.io.File f) {
    return f.isDirectory() && f.canWrite();
}

Try / catch

try {
    out = fs.create(path, ...);
} catch (IOException e) {
    if (e.getMessage().contains("not a directory")) {
        // fix hive.s3.staging-directory config or remove the offending file
    }
    throw e;
}

Prevention

When it happens

Trigger: hive.s3.staging-directory (or s3.staging-directory Hadoop config) resolved to a path that is a file; a mount point replaced by a file; wrong path substitution in configs.

Common situations: Config typo where staging dir points at a file (e.g. a symlink to a file); Docker/K8s volume mounted over the directory as a file; leftover artifact from packaging.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/5cec7050678b3e76. Report an issue: GitHub.