{"record":{"id":"e3ee96f2e8e2a11b","repo":"aeron-io/aeron","slug":"failed-to-read-link-file-linkfile","errorCode":null,"errorMessage":"failed to read link file=\" + linkFile","messagePattern":"failed to read link file=\" \\+ linkFile","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/ArchiveTool.java","lineNumber":1165,"sourceCode":"            (version) -> {},\n            null);\n    }\n\n    private static File resolveMarkFileDir(final File archiveDir)\n    {\n        final File linkFile = new File(archiveDir, ArchiveMarkFile.LINK_FILENAME);\n        final File markFileDir;\n        if (linkFile.exists())\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        else\n        {\n            markFileDir = archiveDir;\n        }\n\n        return markFileDir;\n    }\n\n    private static void dump(\n        final PrintStream out,\n        final File archiveDir,\n        final Catalog catalog,\n        final long fragmentCountLimit,\n        final ActionConfirmation<Long> continueActionOnFragmentLimit,\n        final RecordingDescriptorHeaderDecoder header,\n        final RecordingDescriptorDecoder descriptor,","sourceCodeStart":1147,"sourceCodeEnd":1183,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/ArchiveTool.java#L1147-L1183","documentation":"resolveMarkFileDir reads the archive link file (archive-marker.lnk style file inside the archive dir) that points to the real mark-file directory, and wraps any IOException from Files.readAllBytes in a RuntimeException 'failed to read link file=...'. This means the link file exists but could not be read (permissions, IO error, or a race where it disappeared).","triggerScenarios":"Opening the mark file (openMarkFile/openMarkFileReadWrite) when the archive directory contains a link file whose readAllBytes throws IOException: file deleted between exists() and read, unreadable permissions, disk IO error, or a bad/unreadable filesystem mount.","commonSituations":"Archive dir on an NFS/unstable mount; file permissions changed after container restart; concurrent tool removed the link file; read-only or failing disk.","solutions":["Check OS-level permissions on the link file and archive directory (read access for the tool's user).","Confirm the link file still exists and the archive directory is on a healthy, mounted filesystem.","If the link file is stale/incorrect, restore it (or let a healthy archive recreate it) and retry."],"exampleFix":"// before\n// link file unreadable -> RuntimeException('failed to read link file=...')\n// after\n// fix permissions, then retry:\n// chmod u+r /data/archive/archive-marker.lnk  (run as the archive user)","handlingStrategy":"try-catch","validationCode":"File linkFile = new File(archiveDir, ArchiveTool.ARCHIVE_MARK_FILE_NAME + \".lnk\");\nif (linkFile.exists() && (!linkFile.canRead() || !linkFile.isFile())) {\n    throw new IllegalStateException(\"link file unreadable: \" + linkFile);\n}","typeGuard":null,"tryCatchPattern":"try (ArchiveMarkFile markFile = openMarkFile(archiveDir, out::println)) {\n    ...\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"failed to read link file=\")) {\n        // check permissions/mount, then retry with backoff\n    } else throw e;\n}","preventionTips":["Run archive tooling as the same user that owns the archive directory files.","Avoid deleting or touching files inside the archive dir while tools are running.","Monitor mounts (NFS/EBS) hosting archive dirs for IO errors.","Restore a consistent archive directory from backup if the link file is corrupt."],"tags":["aeron","archive","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-15T23:17:13.987Z"}