aeron-io/aeron · error · ArchiveException
failed to create mark file dir
Error message
failed to create mark file dir: ${markFileDir.getAbsolutePath()} What it means
ClusterBackup.Context.conclude() also ensures the mark file directory exists, defaulting it to the cluster dir or the ClusteredServiceContainer markFileDir configuration. If that directory does not exist and mkdirs() fails, it throws an ArchiveException with the directory's absolute path. Same filesystem failure modes as the cluster dir, but for the backup mark file location.
Solutions
- Fix permissions/ownership on the configured mark file dir path (or its parent).
- Set markFileDir explicitly to a writable location, or leave it unset so it defaults to the (already created) cluster dir.
- Check the path is not blocked by an existing non-directory file.
- In containers, ensure the mounted volume is writable for the running user.
Example fix
// before
ctx.markFileDir(new File("/readonly/mark")); // mkdirs fails
// after
ctx.markFileDir(new File("/var/lib/aeron/cluster-backup/mark")); // writable Defensive patterns
Strategy: validation
Validate before calling
File mfd = markFileDir != null ? markFileDir : clusterDir;
if (!mfd.exists() && !mfd.getParentFile().canWrite()) { throw new IllegalStateException("cannot create mark file dir: " + mfd); } Type guard
static boolean markFileDirCreatable(File d) { return d.exists() ? d.isDirectory() : d.getParentFile() != null && d.getParentFile().canWrite(); } Try / catch
try {
ctx.conclude();
} catch (ArchiveException e) {
if (e.getMessage().startsWith("failed to create mark file dir")) { log.error("check markFileDir permissions: {}", e.getMessage()); }
throw e;
} Prevention
- Leave markFileDir unset to inherit the writable cluster dir, or set it to a verified writable path
- Ensure ClusteredServiceContainer.markFileDir config points to an existing, writable directory
- Check for typos causing nested paths that cannot be created
When it happens
Trigger: Concluding a ClusterBackup.Context where markFileDir (explicitly set, or derived from ClusteredServiceContainer.Configuration.markFileDir()) cannot be created by mkdirs().
Common situations: Setting markFileDir to a path under a directory owned by another user; read-only container filesystem; typo in the configured path making a nested tree that cannot be created due to a permission gap midway.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- failed to create cluster dir
- ArchiveMarkFile headerLength=
- ClusterMarkFile headerLength=
- existing Mark file type
- failed to write recording
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/3a384901213a986a.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ClusterBackup.java:720
if (null == catchupEndpoint)
{
throw new ClusterException("ClusterBackup.Context.catchupEndpoint must be set");
}
if (!clusterDir.exists() && !clusterDir.mkdirs())
{
throw new ClusterException("failed to create cluster dir: " + clusterDir.getAbsolutePath());
}
if (null == markFileDir)
{
final String dir = ClusteredServiceContainer.Configuration.markFileDir();
markFileDir = Strings.isEmpty(dir) ? clusterDir : new File(dir);
}
if (!markFileDir.exists() && !markFileDir.mkdirs())
{
throw new ArchiveException("failed to create mark file dir: " + markFileDir.getAbsolutePath());
}
if (null == epochClock)
{
epochClock = SystemEpochClock.INSTANCE;
}
if (Aeron.NULL_VALUE == replicationProgressIntervalNs)
{
replicationProgressIntervalNs = Math.max(replicationProgressTimeoutNs / 10, 1);
}
if (null == markFile)
{
final int filePageSize = null != aeron ? aeron.context().filePageSize() :
driverFilePageSize(new File(aeronDirectoryName), epochClock, new CommonContext().driverTimeoutMs());
markFile = new ClusterMarkFile(
new File(markFileDir, ClusterMarkFile.FILENAME),View on GitHub (pinned to 6d60124e15)