{"record":{"id":"750fcdda7d6a1b69","repo":"aeron-io/aeron","slug":"failed-to-read-link-file-linkfile-clustertooloperator","errorCode":null,"errorMessage":"failed to read link file=${linkFile}","messagePattern":"failed to read link file=(.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/ClusterToolOperator.java","lineNumber":1327,"sourceCode":"    File resolveClusterMarkFileDir(final File dir)\n    {\n        final File linkFile = new File(dir, ClusterMarkFile.LINK_FILENAME);\n        return linkFile.exists() ? resolveDirectoryFromLinkFile(linkFile) : dir;\n    }\n\n    File resolveDirectoryFromLinkFile(final File linkFile)\n    {\n        final File markFileDir;\n\n        try\n        {\n            final byte[] bytes = Files.readAllBytes(linkFile.toPath());\n            final String markFileDirPath = new String(bytes, US_ASCII).trim();\n            markFileDir = new File(markFileDirPath);\n        }\n        catch (final IOException ex)\n        {\n            throw new RuntimeException(\"failed to read link file=\" + linkFile, ex);\n        }\n\n        return markFileDir;\n    }\n\n    /**\n     * Channel to use.\n     *\n     * @return channel to use.\n     */\n    protected String toolChannel()\n    {\n        return toolChannel;\n    }\n\n    /**\n     * Stream id to use.\n     *","sourceCodeStart":1309,"sourceCodeEnd":1345,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/ClusterToolOperator.java#L1309-L1345","documentation":"ClusterToolOperator reads a link file (a small ASCII file pointing at the mark file directory) with Files.readAllBytes; any IOException is rethrown as RuntimeException(\"failed to read link file=...\"). This happens when discovering a cluster's mark file directory via its link file and the file cannot be read.","triggerScenarios":"Constructing/using ClusterToolOperator against a cluster directory containing a link file that cannot be read: file missing, unreadable permissions, path is a directory, or I/O error during readAllBytes.","commonSituations":"Pointing ClusterTool at the wrong directory where the link file is absent; running as a user without read permission; cluster dir mounted but the link file truncated or removed by cleanup jobs.","solutions":["Check the link file exists at the given path and is readable by the tool's user (ls -l, chmod).","Verify you are pointing the tool at the correct cluster directory.","Ensure the link file contains a valid ASCII path to the mark file directory and is not empty or corrupted.","Fix filesystem/mount issues (e.g. stale NFS mount) that cause IOException during read."],"exampleFix":"// before\nFile linkFile = new File(clusterDir, \"link-file\"); // may not exist\noperator.usage(clusterDir, ...);\n// after\nFile linkFile = new File(clusterDir, \"link-file\");\nif (!linkFile.isFile() || !linkFile.canRead())\n{\n    throw new IllegalStateException(\"cannot read link file=\" + linkFile);\n}","handlingStrategy":"validation","validationCode":"File linkFile = new File(clusterDir, \"link-file\");\nif (!linkFile.isFile() || !linkFile.canRead())\n{\n    throw new IllegalStateException(\"link file missing/unreadable: \" + linkFile);\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    operator.usage(clusterDir, ...);\n}\ncatch (RuntimeException ex)\n{\n    if (ex.getMessage() != null && ex.getMessage().startsWith(\"failed to read link file\"))\n    {\n        // check path/permissions\n    }\n    else throw ex;\n}","preventionTips":["Confirm the cluster directory path before running tools.","Ensure the tool user has read access to all files in the cluster dir.","Watch for cleanup scripts deleting cluster-dir files."],"tags":["aeron","cluster","io","file-read"],"backgroundTag":"file-read-failed","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}