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

  1. Check the cause message: 'NoSuchFileException' -> create the source/target parent dirs first; 'FileAlreadyExistsException' -> pass REPLACE_EXISTING or delete the target.
  2. Verify permissions on both source and target with the user running the Vert.x process.
  3. Confirm path resolution: use absolute paths or set the working directory explicitly, remembering fat-jar classpath resolution in FileResolver.
  4. 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

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


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/ed2a2981f1c31394. Report an issue: GitHub.