eclipse-vertx/vert.x · error · FileSystemException
Failed to read ${link}
Error message
Failed to read ${link} What it means
Thrown when FileSystem.readSymbolicLink fails: Vert.x calls Files.readSymbolicLink and wraps any IOException into a FileSystemException built from getFileAccessErrorMessage("read", link) — i.e. 'Failed to read <link>'. It means the path could not be resolved as a symbolic link.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/file/impl/FileSystemImpl.java:658
}
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) {
throw new FileSystemException(getFileAccessErrorMessage("read", link), e);
}
}
};
}
private BlockingAction<Void> deleteInternal(String path) {
return deleteInternal(path, false);
}
private BlockingAction<Void> deleteInternal(String path, boolean recursive) {
Objects.requireNonNull(path);
return new BlockingAction<Void>() {
public Void perform() {
try {
Path source = resolveFile(path).toPath();
delete(source, recursive);
} catch (IOException e) {
throw new FileSystemException(getFileAccessErrorMessage("delete", path), e);View on GitHub (pinned to fb308bd8c3)
Solutions
- Verify the path is a symlink first (check props via lprops and/or symlink attribute) before reading it.
- Confirm the path exists; a missing path also raises IOException here.
- Handle the NotLinkException cause explicitly when the input may be a regular file.
- On non-POSIX filesystems, skip symlink resolution entirely.
Example fix
// before
String target = vertx.fileSystem().readSymbolicLinkBlocking("/app/current"); // fails if not a link
// after
if (vertx.fileSystem().lpropsBlocking("/app/current").isSymbolicLink()) {
String target = vertx.fileSystem().readSymbolicLinkBlocking("/app/current");
} Defensive patterns
Strategy: validation
Validate before calling
FileProps lp = vertx.fileSystem().lpropsBlocking(link);
if (!lp.isSymbolicLink()) throw new IllegalArgumentException("not a symlink: " + link); Try / catch
try { return vertx.fileSystem().readSymbolicLinkBlocking(link); } catch (FileSystemException e) { if (e.getCause() != null && e.getCause().getClass().getSimpleName().equals("NotLinkException")) return link; throw e; } Prevention
- Check lprops().isSymbolicLink() before reading
- Handle regular files as a non-error fallback
- Re-check existence if symlinks may change concurrently
- Skip resolution on filesystems without symlink support
When it happens
Trigger: Calling vertx.fileSystem().readSymbolicLink(link) on a path that is not a symbolic link (NotLinkException, an IOException subtype), a broken symlink, or a path that does not exist.
Common situations: Reading a regular file or directory assuming it was a symlink; resolving symlinks on filesystems that don't support them; TOCTOU where the symlink was replaced between check and read.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Unable to link existing file '${existing}' to '${link}'
- Failed to read ${path}
- Failed to chmod ${path}
- Failed to crown ${path}
- Failed to analyse ${path}
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/47e0e643d633eacd.
Report an issue: GitHub.