{"record":{"id":"3d236fa94dc9e07e","repo":"eclipse-vertx/vert.x","slug":"unable-to-link-existing-file-existing-to-l","errorCode":null,"errorMessage":"Unable to link existing file '${existing}' to '${link}'","messagePattern":"Unable to link existing file '(.+?)' to '(.+?)'","errorType":"exception","errorClass":"FileSystemException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/file/impl/FileSystemImpl.java","lineNumber":639,"sourceCode":"\n  private BlockingAction<Void> link(String link, String existing, boolean symbolic) {\n    Objects.requireNonNull(link);\n    Objects.requireNonNull(existing);\n    return new BlockingAction<Void>() {\n      public Void perform() {\n        try {\n          Path source = resolveFile(link).toPath();\n          Path target = resolveFile(existing).toPath();\n          if (symbolic) {\n            Files.createSymbolicLink(source, target);\n          } else {\n            Files.createLink(source, target);\n          }\n        } catch (IOException e) {\n          final String message = \"Unable to link existing file '\" + existing\n            + \"' to '\" + link\n            + \"'\";\n          throw new FileSystemException(message, e);\n        }\n        return null;\n      }\n    };\n  }\n\n  private BlockingAction<Void> unlinkInternal(String link) {\n    return deleteInternal(link);\n  }\n\n  private BlockingAction<String> readSymlinkInternal(String link) {\n    Objects.requireNonNull(link);\n    return new BlockingAction<String>() {\n      public String perform() {\n        try {\n          Path source = resolveFile(link).toPath();\n          return Files.readSymbolicLink(source).toString();\n        } catch (IOException e) {","sourceCodeStart":621,"sourceCodeEnd":657,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/file/impl/FileSystemImpl.java#L621-L657","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Verify 'existing' exists and the 'link' path does not (existsBlocking on both).","Keep both paths on the same filesystem/volume — hard links cannot cross devices.","On Windows, enable Developer Mode or run with SeCreateSymbolicLinkPrivilege for symlinks.","Inspect getCause() for the exact errno (EEXIST, ENOENT, EXDEV)."],"exampleFix":"// before\nvertx.fileSystem().linkBlocking(\"/mnt/other/link\", \"/app/data/file\"); // EXDEV\n// after\nvertx.fileSystem().linkBlocking(\"/app/data/link\", \"/app/data/file\"); // same filesystem","handlingStrategy":"validation","validationCode":"FileSystem fs = vertx.fileSystem();\nif (!fs.existsBlocking(existing)) throw new FileNotFoundException(existing);\nif (fs.existsBlocking(link)) throw new IllegalStateException(\"link target already exists: \" + link);","typeGuard":null,"tryCatchPattern":"try { vertx.fileSystem().linkBlocking(link, existing); } catch (FileSystemException e) { if (e.getCause() instanceof FileAlreadyExistsException) { /* idempotent: fine */ } else throw e; }","preventionTips":["Keep link and existing on the same filesystem","Check both paths beforehand","Handle FileAlreadyExistsException as idempotent success","On Windows, ensure symlink privileges before symlink()"],"tags":["filesystem","link","symlink","io"],"backgroundTag":"file-write-failed","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}