aeron-io/aeron · critical · ArchiveException

incompatible catalog file version " +…

Error message

incompatible catalog file version " + SemanticVersion.toString(version) + ", archive software is " + SemanticVersion.toString(ArchiveMarkFile.SEMANTIC_VERSION)

What it means

When opening an existing catalog file, Catalog verifies the recorded version's major version matches ArchiveMarkFile.MAJOR_VERSION. If an older/newer archive software wrote the catalog with a different major version, opening it is refused with this ArchiveException because the on-disk format is incompatible.

Solutions

  1. Align the archive software version with the version that wrote the catalog (major version must match).
  2. Back up the archive directory, then migrate/recreate the catalog with a compatible tool version.
  3. If intentional, use the Catalog constructor that accepts a custom versionCheck to permit the version.

Example fix

// before: opening an old catalog with a newer incompatible library
Archive archive = Archive.launch(configWithArchiveDir("/var/aeron/archive")); // throws
// after: run the archive with the same major version that created the catalog
// or supply a versionCheck that accepts the stored version:
new Catalog(archiveDir, clock, null, fileSyncLevel, (version) -> true, wirePool);
Defensive patterns

Strategy: validation

Validate before calling

// Check catalog version before opening
final int version = readCatalogHeaderVersion(archiveDir);
if (SemanticVersion.major(version) != ArchiveMarkFile.MAJOR_VERSION) {
    throw new IllegalStateException("catalog major version " + SemanticVersion.toString(version) +
        " incompatible with archive software " + SemanticVersion.toString(ArchiveMarkFile.SEMANTIC_VERSION));
}

Try / catch

try {
    catalog = new Catalog(archiveDir, clock, null, fileSyncLevel, wirePool);
} catch (ArchiveException e) {
    if (e.getMessage().startsWith("incompatible catalog file version")) {
        // switch to a compatible library version or migrate the archive
    } else { throw e; }
}

Prevention

When it happens

Trigger: Constructing a Catalog (directly or via Archive launch/ArchiveTool) against an existing catalog file whose header version major differs from the running library's ArchiveMarkFile.MAJOR_VERSION, with no versionCheck override on this path.

Common situations: Upgrading or downgrading Aeron across a major version and reusing the old archive directory; running a newer ArchiveTool against an archive produced by an older cluster; mixing archive component versions in the same deployment.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at aeron-archive/src/main/java/io/aeron/archive/Catalog.java:208

            {
                CloseHelper.close(catalogFileChannel);
                LangUtil.rethrowUnchecked(ex);
            }

            catalogChannel = catalogFileChannel;
            initBuffers(catalogMappedByteBuffer);

            final UnsafeBuffer catalogHeaderBuffer = new UnsafeBuffer(catalogByteBuffer);
            catalogHeaderDecoder.wrap(
                catalogHeaderBuffer, 0, CatalogHeaderDecoder.BLOCK_LENGTH, CatalogHeaderDecoder.SCHEMA_VERSION);
            catalogHeaderEncoder.wrap(catalogHeaderBuffer, 0);

            if (catalogExists)
            {
                final int version = catalogHeaderDecoder.version();
                if (SemanticVersion.major(version) != ArchiveMarkFile.MAJOR_VERSION)
                {
                    throw new ArchiveException(
                        "incompatible catalog file version " + SemanticVersion.toString(version) +
                        ", archive software is " + SemanticVersion.toString(ArchiveMarkFile.SEMANTIC_VERSION));
                }

                alignment = catalogHeaderDecoder.alignment();
                nextRecordingId = catalogHeaderDecoder.nextRecordingId();
            }
            else
            {
                alignment = CACHE_LINE_LENGTH;

                catalogHeaderEncoder
                    .version(ArchiveMarkFile.SEMANTIC_VERSION)
                    .length(CatalogHeaderEncoder.BLOCK_LENGTH)
                    .nextRecordingId(nextRecordingId)
                    .alignment(alignment);

                forceWrites(archiveDirChannel);

View on GitHub (pinned to 6d60124e15)