SonarSource/sonarqube · error · IllegalStateException
Can not unzip file to directory
Error message
Can not unzip file ${zipFile} to directory ${toDir} What it means
Files2.unzipToDir wraps any IOException from unzipping an archive into an IllegalStateException, since in the compute-engine task context a failed unzip is unrecoverable. It means the zip file could not be read or its entries extracted to the target directory. The original IOException is preserved as the cause.
Solutions
- Verify the zip file exists, is non-empty and readable by the CE process user
- Check the target directory can be created/written (permissions, disk space)
- Regenerate or re-download the zip file if corrupt
- Check the cause IOException in the stack trace for the underlying reason
Example fix
// before
files2.unzipToDir(zipFile, toDir);
// after
if (!zipFile.isFile() || !zipFile.canRead()) {
throw new IllegalStateException("Zip file missing or unreadable: " + zipFile);
}
files2.unzipToDir(zipFile, toDir); Defensive patterns
Strategy: try-catch
Validate before calling
if (!zipFile.isFile() || !zipFile.canRead() || zipFile.length() == 0) {
throw new IllegalArgumentException("Zip file missing, unreadable or empty: " + zipFile);
}
if (toDir.exists() && !toDir.isDirectory()) {
throw new IllegalArgumentException("Target exists and is not a directory: " + toDir);
} Type guard
boolean isReadableZip(File f) {
return f != null && f.isFile() && f.canRead() && f.length() > 0;
} Try / catch
try {
files2.unzipToDir(zipFile, toDir);
} catch (IllegalStateException e) {
LOGGER.error("Unzip failed for {}", zipFile, e.getCause());
// cleanup partial toDir, fail task or fall back
} Prevention
- Check file existence/readability before unzipping
- Monitor disk space on the workspace volume
- Validate zip integrity (checksum) after download/transfer
- Run the process as a user with write access to the target directory
When it happens
Trigger: Calling unzipToDir(zipFile, toDir) when the zip file is missing/corrupt/truncated, unreadable (permissions), or when toDir cannot be created or written.
Common situations: Worker telemetry/report directories on disk full or with wrong permissions; partially downloaded or corrupted zip files; toDir path occupied by a regular file.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/0955b1098559a3a7.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/util/Files2.java:240
*/
public void unzipToDirOrThrowIOE(File zipFile, File toDir) throws IOException {
checkOrThrowIOE(!zipFile.isDirectory(), "File %s exists but is a directory", zipFile);
checkOrThrowIOE(zipFile.exists(), "File %s does not exist", zipFile);
ZipUtils.unzip(zipFile, toDir);
}
/**
* Unzips a file to the specified directory. The directory is created if it does not exist.
*
* @throws IllegalStateException if {@code zipFile} is a directory
* @throws IllegalStateException if {@code zipFile} does not exist
* @throws IllegalStateException if {@code toDir} can not be created
*/
public void unzipToDir(File zipFile, File toDir) {
try {
unzipToDirOrThrowIOE(zipFile, toDir);
} catch (IOException e) {
throw new IllegalStateException("Can not unzip file " + zipFile + " to directory " + toDir, e);
}
}
/**
* Zips the directory {@code dir} to the file {@code toFile}. If {@code toFile} is overridden
* if it exists, else it is created.
*
* @throws IllegalStateException if {@code dir} is a not directory
* @throws IllegalStateException if {@code dir} does not exist
* @throws IllegalStateException if {@code toFile} can not be created
*/
public void zipDirOrThrowIOE(File dir, File toFile) throws IOException {
checkOrThrowIOE(dir.exists(), "Directory %s does not exist", dir);
checkOrThrowIOE(dir.isDirectory(), "File %s exists but is not a directory", dir);
ZipUtils.zipDir(dir, toFile);
}
/**View on GitHub (pinned to 184c821202)