eclipse-vertx/vert.x · error · FileSystemException
Failed to move ${from} to ${to}
Error message
Failed to move ${from} to ${to} What it means
The blocking move action in FileSystemImpl wraps IOException from java.nio.file.Files.move into FileSystemException 'Failed to move <from> to <to>'. Vert.x throws it when fileSystem().move/moveBlocking cannot rename or relocate the file at the OS level. The cause distinguishes missing source, existing target, or cross-filesystem issues.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/file/impl/FileSystemImpl.java:487
return null;
}
};
}
private BlockingAction<Void> moveInternal(String from, String to, CopyOptions options) {
Objects.requireNonNull(from);
Objects.requireNonNull(to);
Objects.requireNonNull(options);
Set<CopyOption> copyOptionSet = toCopyOptionSet(options);
CopyOption[] copyOptions = copyOptionSet.toArray(new CopyOption[0]);
return new BlockingAction<Void>() {
public Void perform() {
try {
Path source = resolveFile(from).toPath();
Path target = resolveFile(to).toPath();
Files.move(source, target, copyOptions);
} catch (IOException e) {
throw new FileSystemException(getFileMoveErrorMessage(from, to), e);
}
return null;
}
};
}
private BlockingAction<Void> truncateInternal(String p, long len) {
Objects.requireNonNull(p);
return new BlockingAction<Void>() {
public Void perform() {
try {
String path = resolveFile(p).getAbsolutePath();
if (len < 0) {
throw new FileSystemException("Cannot truncate file to size < 0");
}
if (!Files.exists(Paths.get(path))) {
throw new FileSystemException("Cannot truncate file " + path + ". Does not exist");
}View on GitHub (pinned to fb308bd8c3)
Solutions
- Check cause: NoSuchFileException -> verify source path; FileAlreadyExistsException -> add REPLACE_EXISTING or delete target first.
- For cross-filesystem moves, don't combine with ATOMIC_MOVE (or fall back to copy+delete) since rename(2) fails across devices.
- Close all streams/handles reading the source before moving; on Windows ensure antivirus/indexers release the lock.
- Create the target parent directory before the move.
Example fix
// before
vertx.fileSystem().moveBlocking("/tmp/upload/f.bin", "/data/f.bin"); // cross-device
// after: copy then delete
vertx.fileSystem().copyBlocking("/tmp/upload/f.bin", "/data/f.bin");
vertx.fileSystem().deleteBlocking("/tmp/upload/f.bin"); Defensive patterns
Strategy: validation
Validate before calling
FileSystem fs = vertx.fileSystem();
if (!fs.existsBlocking(from)) throw new FileNotFoundException(from);
if (fs.existsBlocking(to) && !overwrite) throw new FileAlreadyExistsException(to);
Files.createDirectories(Paths.get(to).getParent());
if (Paths.get(from).toFile().getFreeSpace() == 0 ||
!Paths.get(from).toFile().equalsSamePathIfAtomic) { /* same-volume check */ }
if (!Files.isWritable(Paths.get(from).getParent())) throw new AccessDeniedException(from); Type guard
static boolean isRenameable(Path from, Path to, boolean overwrite) {
try {
boolean sameVolume = Files.getFileStore(from).equals(Files.getFileStore(to.getParent()));
return Files.exists(from) && sameVolume && (overwrite || !Files.exists(to));
} catch (IOException e) { return false; }
} Try / catch
try {
fs.moveBlocking(from, to);
} catch (FileSystemException e) {
if (e.getCause() instanceof AtomicMoveNotSupportedException
|| e.getCause() instanceof FileSystemException) {
fs.copyBlocking(from, to, StandardCopyOption.REPLACE_EXISTING);
fs.deleteBlocking(from); // fallback: copy+delete across devices
} else throw e;
} Prevention
- Close all readers/writers of the source file before moving (Windows especially)
- Check source and target are on the same filesystem if relying on atomic rename
- Delete or REPLACE_EXISTING the target before moving
- Create the target parent directory first
When it happens
Trigger: vertx.fileSystem().move(from, to) where the source does not exist, the target exists without REPLACE_EXISTING, the target is on a different filesystem without ATOMIC_MOVE compatibility, or the source file is locked/open by another process (notably Windows).
Common situations: Moving a log/upload file while it is still being written; rename across mount points (e.g. /tmp to /app on different devices); target filename collision; Windows file locks from scanners or other readers; ATOMIC_MOVE combined with cross-device rename.
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
- Failed to unpack ${url}
- Failed to copy ${from} to ${to}
- Failed to truncate ${p}
- Nesting more than two levels is not supported
- Cannot truncate file to size < 0
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/708247f658bff984.
Report an issue: GitHub.