aeron-io/aeron · critical · AgentTerminationException

incompatible version…

Error message

incompatible version: <SemanticVersion.toString(ctx.appVersion())> log=<SemanticVersion.toString(appVersion)>

What it means

When a new leadership term begins, ClusteredServiceAgent checks the log's appVersion against the context's appVersion using ctx.appVersionValidator().isVersionCompatible; if incompatible, it logs a ClusterException via the error handler and throws AgentTerminationException to stop the service. The log header's semantic version must be compatible with the service's declared version.

Solutions

  1. Align versions: run the service whose ctx.appVersion() matches the log's appVersion (or is compatible per the validator).
  2. Adjust appVersionValidator() if your upgrade policy allows compatibility (e.g. same-major check) and bump ctx.appVersion() accordingly during upgrades.
  3. Restore the correct log/snapshot set for this service, or drain and cleanly re-cluster with a consistent version across all nodes.

Example fix

// before
ctx.appVersion(SemanticVersion.compose(1, 0, 0)); // log is 2.0.0
// after
// either match the log
ctx.appVersion(SemanticVersion.compose(2, 0, 0));
// or relax the validator
ctx.appVersionValidator((current, log) -> SemanticVersion.major(current) == SemanticVersion.major(log));
Defensive patterns

Strategy: validation

Validate before calling

// java: validate versions before starting the service container
int logVersion = readLogAppVersion(clusterDir); // from the log header / recovery plan
if (!ctx.appVersionValidator().isVersionCompatible(ctx.appVersion(), logVersion)) {
    throw new IllegalStateException("service appVersion " + SemanticVersion.toString(ctx.appVersion()) +
        " incompatible with log " + SemanticVersion.toString(logVersion));
}

Try / catch

try {
    serviceContainer.start();
} catch (AgentTerminationException e) {
    // often preceded by "incompatible version" in the error log;
    // stop, fix appVersion or redeploy the matching binary, then restart
}

Prevention

When it happens

Trigger: A clustered service starting (or taking on a new leadership term) over a log whose recorded appVersion fails the configured version validator — typically after upgrading or downgrading the service binary without a compatible appVersion.

Common situations: Rolling deployment where a new service version is incompatible with the log written by the old version; forgetting to set/advance ctx.appVersion() when the validator requires an exact major match; replaying a log from a different cluster 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/2d78b16e53080e1e. Report an issue: GitHub.

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/service/ClusteredServiceAgent.java:597

        executeAction(action, logPosition, leadershipTermId, flags);
    }

    void onNewLeadershipTermEvent(
        final long leadershipTermId,
        final long logPosition,
        final long timestamp,
        final long termBaseLogPosition,
        final int leaderMemberId,
        final int logSessionId,
        final TimeUnit timeUnit,
        final int appVersion)
    {
        if (!ctx.appVersionValidator().isVersionCompatible(ctx.appVersion(), appVersion))
        {
            ctx.countedErrorHandler().onError(new ClusterException(
                "incompatible version: " + SemanticVersion.toString(ctx.appVersion()) +
                " log=" + SemanticVersion.toString(appVersion)));
            throw new AgentTerminationException();
        }

        sessionMessageHeaderEncoder.leadershipTermId(leadershipTermId);
        this.logPosition = logPosition;
        clusterTime = timestamp;
        this.timeUnit = timeUnit;

        service.onNewLeadershipTermEvent(
            leadershipTermId,
            logPosition,
            timestamp,
            termBaseLogPosition,
            leaderMemberId,
            logSessionId,
            timeUnit,
            appVersion);
    }

View on GitHub (pinned to 6d60124e15)