SonarSource/sonarqube · error · IllegalStateException

Can not move file to

Error message

Can not move file  to 

What it means

Files2.moveFile(File from, File to) moves a file, translating any IOException from moveFileOrThrowIOE into an IllegalStateException with the message "Can not move file <from> to <to>". It is thrown whenever the filesystem cannot complete the move (rename) operation.

Source

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

  public void moveFileOrThrowIOE(File from, File to) throws IOException {
    org.apache.commons.io.FileUtils.moveFile(from, to);
  }

  /**
   * Like {@link #moveFileOrThrowIOE(File, File)} but wraps {@link IOException}
   * into {@link IllegalStateException}.
   *
   * @param from the file to be moved
   * @param to the destination file
   * @throws IllegalStateException if the destination file exists
   * @throws IllegalStateException if source or destination is invalid
   * @throws IllegalStateException if an IO error occurs moving the file
   */
  public void moveFile(File from, File to) {
    try {
      moveFileOrThrowIOE(from, to);
    } catch (IOException e) {
      throw new IllegalStateException("Can not move file " + from + " to " + to, e);
    }
  }

  /**
   * Opens a {@link FileOutputStream} for the specified file, checking and
   * creating the parent directory if it does not exist.
   * <p>
   * The parent directory will be created if it does not exist.
   * The file will be created if it does not exist.
   *
   * @param file  the file to open for output, must not be {@code null}
   * @param append if {@code true}, then bytes will be added to the
   * end of the file rather than overwriting
   * @return a new {@link FileOutputStream} for the specified file
   * @throws IOException if the specified file is a directory
   * @throws IOException if the file can not be written to
   * @throws IOException if a parent directory can not be created
   */

View on GitHub (pinned to 184c821202)

Solutions

  1. Ensure the source file exists and the destination's parent directory exists and is writable
  2. Keep source and destination on the same filesystem so an atomic rename is possible
  3. Check for other processes locking either file and stop them
  4. Verify free disk space on the destination volume

Example fix

// before
files2.moveFile(report, new File("/other-volume/out/report.bin"));
// after
File destDir = new File("/other-volume/out");
if (destDir.isDirectory() || destDir.mkdirs()) {
  files2.moveFile(report, new File(destDir, "report.bin"));
}
Defensive patterns

Strategy: validation

Validate before calling

if (!from.isFile()) throw new IllegalStateException("Source missing: " + from);
File parent = to.getParentFile();
if (parent != null && !parent.isDirectory() && !parent.mkdirs()) {
  throw new IllegalStateException("Cannot create dest dir: " + parent);
}

Try / catch

try {
  files2.moveFile(from, to);
} catch (IllegalStateException e) {
  LOGGER.error("Move {} -> {} failed: {}", from, to, e.getCause(), e);
  // fall back to copy + delete if cross-device
}

Prevention

When it happens

Trigger: moveFileOrThrowIOE throws IOException — source missing or unreadable, target exists as a directory, target directory missing or unwritable, cross-device move that fails, or the file is locked by another process.

Common situations: Moving dump files between different mount points where rename fails; target directory not created beforehand; another CE process holding the file open; running out of space when the move falls back to copy+delete.

Related errors


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