aeron-io/aeron · critical · ClusterException

incompatible version

Error message

incompatible version: <appVersion> snapshot=<snapshotAppVersion>

What it means

When loading a snapshot the consensus module compares the application version recorded in the snapshot against the configured app version using ctx.appVersionValidator(). If they are incompatible it throws a FATAL ClusterException because replaying a snapshot made by incompatible service code would corrupt state.

Solutions

  1. Take a fresh snapshot with the old version, then upgrade and start the new version from that snapshot.
  2. Configure the app version validator / semanticVersionCheck to permit the version transition you intend.
  3. Restore a snapshot matching the currently running application version.
  4. If intentional, adjust ctx.appVersion() so it is compatible with the snapshot's recorded version.

Example fix

// before: appVersion bumped 1.2 -> 2.0, old snapshot replayed
// after: snapshot on old version first
curl cluster/snapshot  # while still on 1.2, then deploy 2.0
Defensive patterns

Strategy: validation

Validate before calling

// before loading
int snapshotVersion = readSnapshotAppVersion(clusterDir);
if (!ctx.appVersionValidator().isVersionCompatible(ctx.appVersion(), snapshotVersion)) {
    throw new IllegalStateException("snapshot appVersion " + SemanticVersion.toString(snapshotVersion) + " incompatible");
}

Try / catch

try { cluster.start(); } catch (ClusterException e) { if (e.getMessage().startsWith("incompatible version")) { restoreCompatibleSnapshot(); } else { throw e; } }

Prevention

When it happens

Trigger: onLoadBeginSnapshot receives an appVersion from the snapshot header that fails ClusterVersionValidator/isVersionCompatible against the currently configured ctx.appVersion(), e.g. starting a cluster on a newer (or older) major application version with an old snapshot.

Common situations: Upgrading cluster services without taking a fresh snapshot; rolling back an upgrade with a snapshot written by newer code; misconfigured appVersion in the consensus module context.

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/9abf109c741051c1. Report an issue: GitHub.

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModuleAgent.java:637

     * {@inheritDoc}
     */
    @Override
    public int clusterId()
    {
        return ctx.clusterId();
    }

    public ClusterMember clusterMember()
    {
        return thisMember;
    }

    public void onLoadBeginSnapshot(
        final int appVersion, final TimeUnit timeUnit, final DirectBuffer buffer, final int offset, final int length)
    {
        if (!ctx.appVersionValidator().isVersionCompatible(ctx.appVersion(), appVersion))
        {
            throw new ClusterException(
                "incompatible version: " + SemanticVersion.toString(ctx.appVersion()) +
                " snapshot=" + SemanticVersion.toString(appVersion),
                AeronException.Category.FATAL);
        }

        if (timeUnit != clusterTimeUnit)
        {
            throw new ClusterException(
                "incompatible time unit: " + clusterTimeUnit + " snapshot=" + timeUnit, AeronException.Category.FATAL);
        }
    }

    public ControlledFragmentHandler.Action onExtensionMessage(
        final int actingBlockLength,
        final int templateId,
        final int schemaId,
        final int actingVersion,
        final DirectBuffer buffer,

View on GitHub (pinned to 6d60124e15)