{"record":{"id":"5665a8cc8632f3d4","repo":"prestodb/presto","slug":"spill-path-s-is-not-writable-adjust-experimental","errorCode":null,"errorMessage":"spill path %s is not writable; adjust experimental.spiller-spill-path config property or filesystem permissions","messagePattern":"spill path (.+?) is not writable; adjust experimental\\.spiller-spill-path config property or filesystem permissions","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"critical","filePath":"presto-main-base/src/main/java/com/facebook/presto/spiller/FileSingleStreamSpillerFactory.java","lineNumber":110,"sourceCode":"            double maxUsedSpaceThreshold,\n            CompressionCodec spillCompressionCodec,\n            boolean spillEncryptionEnabled)\n    {\n        this.serdeFactory = new PagesSerdeFactory(requireNonNull(blockEncodingSerde, \"blockEncodingSerde is null\"), spillCompressionCodec);\n        this.executor = requireNonNull(executor, \"executor is null\");\n        this.spillerStats = requireNonNull(spillerStats, \"spillerStats can not be null\");\n        requireNonNull(spillPaths, \"spillPaths is null\");\n        this.spillPaths = ImmutableList.copyOf(spillPaths);\n        spillPaths.forEach(path -> {\n            try {\n                createDirectories(path);\n            }\n            catch (IOException e) {\n                throw new IllegalArgumentException(\n                        format(\"could not create spill path %s; adjust experimental.spiller-spill-path config property or filesystem permissions\", path), e);\n            }\n            if (!path.toFile().canWrite()) {\n                throw new IllegalArgumentException(\n                        format(\"spill path %s is not writable; adjust experimental.spiller-spill-path config property or filesystem permissions\", path));\n            }\n        });\n        this.maxUsedSpaceThreshold = maxUsedSpaceThreshold;\n        this.spillEncryptionEnabled = spillEncryptionEnabled;\n        this.roundRobinIndex = 0;\n    }\n\n    @PostConstruct\n    public void cleanupOldSpillFiles()\n    {\n        spillPaths.forEach(FileSingleStreamSpillerFactory::cleanupOldSpillFiles);\n    }\n\n    @PreDestroy\n    public void destroy()\n    {\n        executor.shutdownNow();","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/spiller/FileSingleStreamSpillerFactory.java#L92-L128","documentation":"FileSingleStreamSpillerFactory validates at construction that every configured spill path exists and is writable via File.canWrite(). If a configured spill directory is not writable by the Presto process user, it throws IllegalArgumentException immediately rather than failing later mid-query. This fails fast so misconfigured spill storage is detected before any spilling workload runs.","triggerScenarios":"Creating a FileSingleStreamSpillerFactory (e.g. during LocalTempStorage/SpillerFactory initialization) when a path listed in experimental.spiller-spill-path (or spiller-spill-path in newer configs) points to a directory the OS user running Presto cannot write to, or to a path whose parent is not accessible.","commonSituations":"Spill directory owned by root while Presto runs as 'presto' user; directory permissions changed by security tooling; container image with read-only or non-created spill mount; spilling path on a read-only NFS mount; leftover wrong path in etc/properties after migrating nodes.","solutions":["Check and fix filesystem permissions: chown -R presto:presto <spill-path> or chmod to allow write for the Presto process user.","Verify the configured path is correct: set experimental.spiller-spill-path in config.properties to an existing, writable directory (e.g. /var/presto/temp).","If running in a container/Kubernetes, ensure the volume mounted at the spill path is read-write and the container runs as a user with write access.","Confirm the disk backing the spill path is not mounted read-only (mount | grep <path>) and remount rw if needed."],"exampleFix":"// before (config.properties)\nexperimental.spiller-spill-path=/mnt/ro-disk/spill\n\n// after\nexperimental.spiller-spill-path=/var/spill  # mkdir -p /var/spill && chown presto:presto /var/spill","handlingStrategy":"validation","validationCode":"// before constructing the spiller factory / starting the server\nfor (Path p : spillPaths) {\n    java.io.File f = p.toFile();\n    if (!f.exists() || !f.isDirectory() || !f.canWrite()) {\n        throw new IllegalStateException(\"Spill path not writable: \" + p);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provision spill dirs with the same ownership as the Presto service user in deployment automation","Add a startup smoke test that writes/deletes a temp file in each spill path","Keep spill paths on local writable mounts, not read-only images or volumes"],"tags":["spill","filesystem","permissions","configuration","presto"],"backgroundTag":"spill-path-not-writable","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}