prestodb/presto · critical · IllegalArgumentException

spill path %s is not writable; adjust experimental.spiller-s

Error message

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

What it means

During LocalTempStorage.initialize(), after creating each spill path it checks path.toFile().canWrite() and throws IllegalArgumentException 'spill path %s is not writable...' if the check fails. Initialization fails fast when the Presto process lacks write permission on a configured spill directory.

Source

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

    {
        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);
    }

    @Override
    public InputStream open(TempDataOperationContext context, TempStorageHandle handle)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Grant write access: chown presto:presto <spill-path> or chmod u+w <spill-path>.
  2. If in Kubernetes, set the volume's readOnly to false and ensure the pod's securityContext fsUser can write.
  3. Verify as the running user: sudo -u presto touch <spill-path>/.writetest.
  4. Update experimental.spiller-spill-path to a directory the service user actually owns.

Example fix

// before
// dr-xr-xr-x root root /var/spill

// after (shell)
// chown presto:presto /var/spill && chmod u+rwx /var/spill
Defensive patterns

Strategy: validation

Validate before calling

for (Path p : spillPaths) {
    java.io.File f = p.toFile();
    if (!f.canWrite()) {
        throw new IllegalStateException("Spill path not writable by current user " + System.getProperty("user.name") + ": " + p);
    }
}

Prevention

When it happens

Trigger: Constructing LocalTempStorage when a successfully created/existing spill directory returns canWrite()==false — directory owned by another user, read-only mode bits, or read-only mount for the process user.

Common situations: Presto running as non-root user while spill dir created by root; chmod 555 applied by hardening scripts; Kubernetes volume mounted readOnly:true; shared directory with restricted ACLs.

Related errors


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