eclipse-vertx/vert.x · error · FileSystemException
Failed to copy ${from} to ${to}
Error message
Failed to copy ${from} to ${to} What it means
The blocking copy action in FileSystemImpl (simple, non-recursive variant) wraps IOException from java.nio.file.Files.copy into FileSystemException 'Failed to copy <from> to <to>'. Vert.x throws it when a fileSystem().copy/copyBlocking call cannot complete at the OS level. The cause IOException details the precise reason (missing source, existing target, permissions).
Source
Thrown at vertx-core/src/main/java/io/vertx/core/file/impl/FileSystemImpl.java:425
static String getFileDualOperationErrorMessage(String action, String from, String to) {
return "Unable to " + action + " file from '" + from + "' to '" + to + "'";
}
private BlockingAction<Void> copyInternal(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.copy(source, target, copyOptions);
} catch (IOException e) {
throw new FileSystemException(getFileCopyErrorMessage(from, to), e);
}
return null;
}
};
}
private BlockingAction<Void> copyRecursiveInternal(String from, String to, boolean recursive) {
Objects.requireNonNull(from);
Objects.requireNonNull(to);
return new BlockingAction<Void>() {
public Void perform() {
try {
Path source = resolveFile(from).toPath();
Path target = resolveFile(to).toPath();
if (recursive) {
Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
new SimpleFileVisitor<Path>() {
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)View on GitHub (pinned to fb308bd8c3)
Solutions
- Check the cause message: 'NoSuchFileException' -> create the source/target parent dirs first; 'FileAlreadyExistsException' -> pass REPLACE_EXISTING or delete the target.
- Verify permissions on both source and target with the user running the Vert.x process.
- Confirm path resolution: use absolute paths or set the working directory explicitly, remembering fat-jar classpath resolution in FileResolver.
- If you need recursive copy, use copy(from, to, true) — the non-recursive variant fails on directories.
Example fix
// before
vertx.fileSystem().copyBlocking("a.txt", "b.txt"); // fails if b.txt exists
// after
vertx.fileSystem().copyBlocking("a.txt", "b.txt",
java.nio.file.StandardCopyOption.REPLACE_EXISTING); Defensive patterns
Strategy: validation
Validate before calling
FileSystem fs = vertx.fileSystem(); if (!fs.existsBlocking(from)) throw new FileNotFoundException(from); Path t = Paths.get(to); if (Files.exists(t) && !overwrite) throw new FileAlreadyExistsException(to); if (t.getParent() != null) Files.createDirectories(t.getParent()); if (!Files.isReadable(Paths.get(from))) throw new AccessDeniedException(from);
Type guard
static boolean isCopyable(Path from, Path to, boolean overwrite) {
return Files.isRegularFile(from) && Files.isReadable(from)
&& (overwrite || !Files.exists(to)) && Files.isDirectory(to.getParent());
} Try / catch
try {
fs.copyBlocking(from, to);
} catch (FileSystemException e) {
if (e.getCause() instanceof FileAlreadyExistsException) {
fs.copyBlocking(from, to, StandardCopyOption.REPLACE_EXISTING);
} else throw e;
} Prevention
- Create target parent directories before copying
- Pass REPLACE_EXISTING when overwriting is intended
- Use absolute paths to avoid fat-jar relative-path resolution surprises
- Use copy(from, to, true) for directories
When it happens
Trigger: vertx.fileSystem().copy(from, to) or copyBlocking where resolveFile(from) doesn't exist, the target parent doesn't exist, the target exists without REPLACE_EXISTING, or the process lacks read/write permissions on either path.
Common situations: Typo in source path; target directory not created beforehand; copy over an existing file without CopyOption REPLACE_EXISTING; copying across filesystems without proper options; relative paths resolved against unexpected working directory in a fat jar.
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 move ${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/ed2a2981f1c31394.
Report an issue: GitHub.