aeron-io/aeron · error · RuntimeException

failed to read link file=" + linkFile

Error message

failed to read link file=" + linkFile

What it means

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).

Solutions

  1. Check OS-level permissions on the link file and archive directory (read access for the tool's user).
  2. Confirm the link file still exists and the archive directory is on a healthy, mounted filesystem.
  3. If the link file is stale/incorrect, restore it (or let a healthy archive recreate it) and retry.

Example fix

// before
// link file unreadable -> RuntimeException('failed to read link file=...')
// after
// fix permissions, then retry:
// chmod u+r /data/archive/archive-marker.lnk  (run as the archive user)
Defensive patterns

Strategy: try-catch

Validate before calling

File linkFile = new File(archiveDir, ArchiveTool.ARCHIVE_MARK_FILE_NAME + ".lnk");
if (linkFile.exists() && (!linkFile.canRead() || !linkFile.isFile())) {
    throw new IllegalStateException("link file unreadable: " + linkFile);
}

Try / catch

try (ArchiveMarkFile markFile = openMarkFile(archiveDir, out::println)) {
    ...
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("failed to read link file=")) {
        // check permissions/mount, then retry with backoff
    } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: Archive dir on an NFS/unstable mount; file permissions changed after container restart; concurrent tool removed the link file; read-only or failing disk.

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


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/e3ee96f2e8e2a11b. Report an issue: GitHub.

Appendix: source

Thrown at aeron-archive/src/main/java/io/aeron/archive/ArchiveTool.java:1165

            (version) -> {},
            null);
    }

    private static File resolveMarkFileDir(final File archiveDir)
    {
        final File linkFile = new File(archiveDir, ArchiveMarkFile.LINK_FILENAME);
        final File markFileDir;
        if (linkFile.exists())
        {
            try
            {
                final byte[] bytes = Files.readAllBytes(linkFile.toPath());
                final String markFileDirPath = new String(bytes, US_ASCII).trim();
                markFileDir = new File(markFileDirPath);
            }
            catch (final IOException ex)
            {
                throw new RuntimeException("failed to read link file=" + linkFile, ex);
            }
        }
        else
        {
            markFileDir = archiveDir;
        }

        return markFileDir;
    }

    private static void dump(
        final PrintStream out,
        final File archiveDir,
        final Catalog catalog,
        final long fragmentCountLimit,
        final ActionConfirmation<Long> continueActionOnFragmentLimit,
        final RecordingDescriptorHeaderDecoder header,
        final RecordingDescriptorDecoder descriptor,

View on GitHub (pinned to 6d60124e15)