aeron-io/aeron · critical · IllegalArgumentException

mark file ( ) major version does not match software

Error message

mark file (${markFile}) major version ${majorVersion} does not match software: ${MAJOR_VERSION}

What it means

ArchiveMarkFile.validateVersion throws IllegalArgumentException when the major version encoded in an existing archive mark file does not match the MAJOR_VERSION of the running Aeron Archive software. This guards against opening an archive produced by an incompatible release, which could corrupt metadata. It is a hard compatibility check performed whenever an existing mark file is opened.

Solutions

  1. Check the Aeron version that created the archive directory (printMarkInformation / ArchiveTool describeRecording) and run a matching Archive version.
  2. Upgrade the software to the major version matching the mark file, or migrate/export the archive with a compatible version before upgrading.
  3. If the archive is disposable, delete or regenerate the mark file/catalog in a fresh archive directory.

Example fix

// before
archiveDir = new File("/data/old-archive"); // created by Aeron 1.40, running 2.x -> throws
// after
// run Archive 1.40.x against /data/old-archive, or migrate the archive first
Defensive patterns

Strategy: validation

Validate before calling

int markVersion = readMarkFileVersion(archiveDir); // read version from mark file header
if (SemanticVersion.major(markVersion) != ArchiveMarkFile.MAJOR_VERSION) {
    throw new IllegalStateException("archive major version " + SemanticVersion.major(markVersion) +
        " != software " + ArchiveMarkFile.MAJOR_VERSION);
}

Try / catch

try (ArchiveMarkFile markFile = ArchiveMarkFile.open(archiveDir, errHandler)) {
    ...
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("major version")) {
        // fall back to a compatible Archive version or fail fast with a clear operator message
    }
}

Prevention

When it happens

Trigger: Opening an existing archive directory (via existingMarkFile -> ArchiveMarkFile) whose mark file's encoded major version differs from the software's MAJOR_VERSION, e.g. running a newer or older Aeron Archive against an archive dir created by an incompatible major release.

Common situations: Upgrading Aeron to a new major version while pointing at an old archive directory; pointing a downgraded archive client at an archive created by a newer version; sharing an archive dir between clusters running different Aeron versions.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at aeron-archive/src/main/java/io/aeron/archive/ArchiveMarkFile.java:511

        headerEncoder
            .startTimestamp(ctx.epochClock().time())
            .controlStreamId(ctx.controlStreamId())
            .localControlStreamId(ctx.localControlStreamId())
            .eventsStreamId(ctx.recordingEventsStreamId())
            .headerLength(HEADER_LENGTH)
            .errorBufferLength(ctx.errorBufferLength())
            .archiveId(ctx.archiveId())
            .controlChannel(ctx.controlChannel())
            .localControlChannel(ctx.localControlChannel())
            .eventsChannel(ctx.recordingEventsChannel())
            .aeronDirectory(ctx.aeronDirectoryName());
    }

    private static void validateVersion(final File markFile, final int version)
    {
        if (SemanticVersion.major(version) != MAJOR_VERSION)
        {
            throw new IllegalArgumentException(
                "mark file (" + markFile.getAbsolutePath() + ") major version " + SemanticVersion.major(version) +
                " does not match software: " + MAJOR_VERSION);
        }
    }

    private static int headerOffset(final File file)
    {
        final MappedByteBuffer mappedByteBuffer = IoUtil.mapExistingFile(file, FILENAME);
        try
        {
            final UnsafeBuffer unsafeBuffer =
                new UnsafeBuffer(mappedByteBuffer, 0, HEADER_OFFSET);
            return headerOffset(unsafeBuffer);
        }
        finally
        {
            IoUtil.unmap(mappedByteBuffer);
        }

View on GitHub (pinned to 6d60124e15)