eclipse-vertx/vert.x · error · FileSystemException

Unable to link existing file '${existing}' to '${link}'

Error message

Unable to link existing file '${existing}' to '${link}'

What it means

Thrown when FileSystem.link (hard link) or symlink creation fails: Vert.x calls Files.createLink (or createSymbolicLink) and wraps the resulting IOException into a FileSystemException with this message. It means the link could not be created between the given paths.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/file/impl/FileSystemImpl.java:639

  private BlockingAction<Void> link(String link, String existing, boolean symbolic) {
    Objects.requireNonNull(link);
    Objects.requireNonNull(existing);
    return new BlockingAction<Void>() {
      public Void perform() {
        try {
          Path source = resolveFile(link).toPath();
          Path target = resolveFile(existing).toPath();
          if (symbolic) {
            Files.createSymbolicLink(source, target);
          } else {
            Files.createLink(source, target);
          }
        } catch (IOException e) {
          final String message = "Unable to link existing file '" + existing
            + "' to '" + link
            + "'";
          throw new FileSystemException(message, e);
        }
        return null;
      }
    };
  }

  private BlockingAction<Void> unlinkInternal(String link) {
    return deleteInternal(link);
  }

  private BlockingAction<String> readSymlinkInternal(String link) {
    Objects.requireNonNull(link);
    return new BlockingAction<String>() {
      public String perform() {
        try {
          Path source = resolveFile(link).toPath();
          return Files.readSymbolicLink(source).toString();
        } catch (IOException e) {

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Verify 'existing' exists and the 'link' path does not (existsBlocking on both).
  2. Keep both paths on the same filesystem/volume — hard links cannot cross devices.
  3. On Windows, enable Developer Mode or run with SeCreateSymbolicLinkPrivilege for symlinks.
  4. Inspect getCause() for the exact errno (EEXIST, ENOENT, EXDEV).

Example fix

// before
vertx.fileSystem().linkBlocking("/mnt/other/link", "/app/data/file"); // EXDEV
// after
vertx.fileSystem().linkBlocking("/app/data/link", "/app/data/file"); // same filesystem
Defensive patterns

Strategy: validation

Validate before calling

FileSystem fs = vertx.fileSystem();
if (!fs.existsBlocking(existing)) throw new FileNotFoundException(existing);
if (fs.existsBlocking(link)) throw new IllegalStateException("link target already exists: " + link);

Try / catch

try { vertx.fileSystem().linkBlocking(link, existing); } catch (FileSystemException e) { if (e.getCause() instanceof FileAlreadyExistsException) { /* idempotent: fine */ } else throw e; }

Prevention

When it happens

Trigger: vertx.fileSystem().link(link, existing) or symlink(...) when 'existing' does not exist, the target link path already exists, the two paths are on different filesystems (EXDEV), or the OS refuses link creation (e.g. symlink privileges missing on Windows).

Common situations: Hard-linking across mount points or Docker volumes; creating a symlink where the link name already exists; Windows without Developer Mode / SeCreateSymbolicLinkPrivilege; source file deleted before linking.

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/3d236fa94dc9e07e. Report an issue: GitHub.