{"record":{"id":"e6ac76a5655045fe","repo":"spring-projects/spring-boot","slug":"file-is-not-readable","errorCode":null,"errorMessage":"File '{}' is not readable","messagePattern":"File '(.+?)' is not readable","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/io/ZipFileTarArchive.java","lineNumber":83,"sourceCode":"\tpublic void writeTo(OutputStream outputStream) throws IOException {\n\t\tTarArchiveOutputStream tar = new TarArchiveOutputStream(outputStream);\n\t\ttar.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);\n\t\ttry (ZipFile zipFile = ZipFile.builder().setFile(this.zip).get()) {\n\t\t\tEnumeration<ZipArchiveEntry> entries = zipFile.getEntries();\n\t\t\twhile (entries.hasMoreElements()) {\n\t\t\t\tZipArchiveEntry zipEntry = entries.nextElement();\n\t\t\t\tcopy(zipEntry, zipFile.getInputStream(zipEntry), tar);\n\t\t\t}\n\t\t}\n\t\ttar.finish();\n\t}\n\n\tprivate void assertArchiveHasEntries(File file) {\n\t\ttry (ZipFile zipFile = ZipFile.builder().setFile(file).get()) {\n\t\t\tAssert.state(zipFile.getEntries().hasMoreElements(), () -> \"Archive file '\" + file + \"' is not valid\");\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new IllegalStateException(\"File '\" + file + \"' is not readable\", ex);\n\t\t}\n\t}\n\n\tprivate void copy(ZipArchiveEntry zipEntry, InputStream zip, TarArchiveOutputStream tar) throws IOException {\n\t\tTarArchiveEntry tarEntry = convert(zipEntry);\n\t\ttar.putArchiveEntry(tarEntry);\n\t\tif (tarEntry.isFile()) {\n\t\t\tStreamUtils.copyRange(zip, tar, 0, tarEntry.getSize());\n\t\t}\n\t\ttar.closeArchiveEntry();\n\t}\n\n\tprivate TarArchiveEntry convert(ZipArchiveEntry zipEntry) {\n\t\tbyte linkFlag = (zipEntry.isDirectory()) ? TarConstants.LF_DIR : TarConstants.LF_NORMAL;\n\t\tString entryName = zipEntry.getName();\n\t\tPath entryPath = Path.of(entryName);\n\t\tAssert.state(entryPath.toAbsolutePath().equals(entryPath.toAbsolutePath().normalize()),\n\t\t\t\t() -> \"Malformed zip entry name '%s'\".formatted(entryName));","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/spring-projects/spring-boot/blob/270dfe353fb830fd69b823a8a859287ff103854b/buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/io/ZipFileTarArchive.java#L65-L101","documentation":"ZipFileTarArchive.assertArchiveHasEntries opens the source file with Apache Commons Compress ZipFile.builder().setFile(file).get(). Any IOException — file missing, not a zip, truncated/corrupted, encrypted, or unreadable — is wrapped in IllegalStateException('File <file> is not readable'). This runs in the constructor, so failure prevents the ZipFileTarArchive from being created.","triggerScenarios":"new ZipFileTarArchive(file, owner) or TarArchive.fromZip(file, owner) is called with a File that ZipFile cannot open: the file does not exist, is not a zip, is a truncated/corrupted zip, is encrypted, or has read permissions denied.","commonSituations":"Wrong path to the application archive; a jar/zip corrupted in transfer or by a failed build; file permission denied (chmod, SELinux); an AES-encrypted zip; a file that is actually a tar or plain file.","solutions":["Confirm it is a valid zip: `unzip -l <file>` or `jar tf <file>`.","Re-generate the archive from the source build.","Fix read permissions: `chmod +r <file>` and check SELinux labels."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the source zip before constructing ZipFileTarArchive\nif (!Files.exists(file.toPath()) || !Files.isReadable(file.toPath())) {\n    throw new IllegalArgumentException(\"Zip file missing or unreadable: \" + file);\n}\ntry (org.apache.commons.compress.archivers.zip.ZipFile zf =\n        ZipFile.builder().setFile(file).get()) {\n    if (!zf.getEntries().hasMoreElements()) {\n        throw new IllegalArgumentException(\"Zip file has no entries: \" + file);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    new ZipFileTarArchive(file, owner);\n} catch (IllegalStateException ex) {\n    if (ex.getCause() instanceof IOException\n            && ex.getMessage().startsWith(\"File '\") && ex.getMessage().endsWith(\"is not readable\")) {\n        // hint: validate with `unzip -l <file>` / regenerate the archive\n    }\n    throw ex;\n}","preventionTips":["Validate the source archive (`unzip -l`, `jar tf`) before the build.","Verify checksums on transferred archives to catch truncation.","Ensure read permissions on the archive file in CI workspaces."],"tags":["docker","zip","tar","io","buildpack"],"backgroundTag":null,"analyzedSha":"270dfe353fb830fd69b823a8a859287ff103854b","analyzedAt":"2026-08-11T19:42:06.541Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}