prestodb/presto · critical · IllegalArgumentException

could not create spill path %s; adjust experimental.spiller-

Error message

could not create spill path %s; adjust experimental.spiller-spill-path config property or filesystem permissions

What it means

LocalTempStorage.initialize() mirrors FileSingleStreamSpillerFactory's constructor validation: for every configured spill path it attempts Files.createDirectories(). On IOException it throws IllegalArgumentException 'could not create spill path %s; adjust experimental.spiller-spill-path config property or filesystem permissions'. Storage initialization aborts when a spill directory cannot be created.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/spiller/LocalTempStorage.java:89

    @GuardedBy("this")
    private int roundRobinIndex;

    public LocalTempStorage(List<Path> spillPaths, double maxUsedSpaceThreshold)
    {
        this.spillPaths = ImmutableList.copyOf(requireNonNull(spillPaths, "spillPaths is null"));
        this.maxUsedSpaceThreshold = maxUsedSpaceThreshold;
        initialize();
    }

    private void initialize()
    {
        // From FileSingleStreamSpillerFactory constructor
        spillPaths.forEach(path -> {
            try {
                createDirectories(path);
            }
            catch (IOException e) {
                throw new IllegalArgumentException(
                        format("could not create spill path %s; adjust experimental.spiller-spill-path config property or filesystem permissions", path), e);
            }
            if (!path.toFile().canWrite()) {
                throw new IllegalArgumentException(
                        format("spill path %s is not writable; adjust experimental.spiller-spill-path config property or filesystem permissions", path));
            }
        });

        // From FileSingleStreamSpillerFactory#cleanupOldSpillFiles
        spillPaths.forEach(LocalTempStorage::cleanupOldSpillFiles);
    }

    @Override
    public TempDataSink create(TempDataOperationContext context)
            throws IOException
    {
        Path path = Files.createTempFile(getNextSpillPath(), SPILL_FILE_PREFIX, SPILL_FILE_SUFFIX);
        return new LocalTempDataSink(path);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Pre-create the directory with correct ownership: mkdir -p <spill-path> && chown presto:presto <spill-path>.
  2. Ensure the configured value is a directory path, not an existing file; remove/rename any conflicting file.
  3. Fix parent-directory permissions so the Presto user can create the leaf directory.
  4. Check SELinux/Deny rules (audit logs) and apply correct contexts or adjust policy.

Example fix

// before (config.properties)
experimental.spiller-spill-path=/nonexistent-parent/spill

// after (shell)
// mkdir -p /var/spill && chown presto:presto /var/spill
experimental.spiller-spill-path=/var/spill
Defensive patterns

Strategy: validation

Validate before calling

for (Path p : spillPaths) {
    if (p.toFile().exists() && !p.toFile().isDirectory()) {
        throw new IllegalStateException("Spill path exists but is not a directory: " + p);
    }
    java.io.File parent = p.toFile().getParentFile();
    if (parent == null || !parent.canWrite()) {
        throw new IllegalStateException("Cannot create spill path, parent not writable: " + p);
    }
}

Prevention

When it happens

Trigger: Constructing LocalTempStorage when Files.createDirectories(path) throws IOException — path's parent is not writable, path exists as a regular file, or a transient I/O error prevents directory creation.

Common situations: Spill path collides with an existing file; parent directory owned by another user; mis-typed path like /var/spil (creating under non-writable /var); immutable container root filesystem; SELinux/AppArmor denying creation.

Related errors


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