SonarSource/sonarqube · error · IllegalStateException

Can not zip directory ${dir} to file ${toFile}

Error message

Can not zip directory ${dir} to file ${toFile}

What it means

Files2.zipDir wraps any IOException from zipping a directory into an IllegalStateException, treating the failure as fatal for the CE task. It means the directory could not be read or the output zip file could not be written.

Source

Thrown at server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/util/Files2.java:270

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

  /**
   * 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 zipDir(File dir, File toFile) {
    try {
      zipDirOrThrowIOE(dir, toFile);
    } catch (IOException e) {
      throw new IllegalStateException("Can not zip directory " + dir + " to file " + toFile, e);
    }
  }

  /**
   * Creates specified directory if it does not exist yet and any non existing parent.
   *
   * @throws IllegalStateException if specified File exists but is not a directory
   * @throws IllegalStateException if directory creation failed
   */
  public void createDir(File dir) {
    Path dirPath = requireNonNull(dir, "dir can not be null").toPath();
    if (dirPath.toFile().exists()) {
      checkState(dirPath.toFile().isDirectory(), "%s is not a directory", dirPath);
    } else {
      try {
        createDirectories(dirPath);
      } catch (IOException e) {
        throw new IllegalStateException(format("Failed to create directory %s", dirPath), e);

View on GitHub (pinned to 184c821202)

Solutions

  1. Verify the source directory exists and is readable
  2. Check the output file's parent directory exists and is writable
  3. Ensure sufficient disk space
  4. Inspect the wrapped IOException cause for the exact failing path

Example fix

// before
files2.zipDir(dir, toFile);
// after
if (!dir.isDirectory() || !dir.canRead()) {
  throw new IllegalStateException("Directory missing or unreadable: " + dir);
}
files2.zipDir(dir, toFile);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!dir.isDirectory() || !dir.canRead()) {
  throw new IllegalArgumentException("Source dir missing or unreadable: " + dir);
}
File parent = toFile.getAbsoluteFile().getParentFile();
if (parent == null || !parent.canWrite()) {
  throw new IllegalArgumentException("Output parent not writable: " + parent);
}

Type guard

boolean canZip(File src, File out) {
  return src != null && src.isDirectory() && src.canRead()
    && out != null && !out.isDirectory()
    && out.getAbsoluteFile().getParentFile().canWrite();
}

Try / catch

try {
  files2.zipDir(dir, toFile);
} catch (IllegalStateException e) {
  LOGGER.error("Zip failed for {} -> {}", dir, toFile, e.getCause());
  // delete partial toFile and report failure
}

Prevention

When it happens

Trigger: Calling zipDir(dir, toFile) when dir does not exist or is unreadable, toFile cannot be created (missing parent, permissions), or disk is full during write.

Common situations: Backing up or packaging analysis working directories; read-protected files inside dir; output volume out of space; toFile path points at an existing directory.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/418851950f95c632. Report an issue: GitHub.