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
- Align versions: run the service whose ctx.appVersion() matches the log's appVersion (or is compatible per the validator).
- Adjust appVersionValidator() if your upgrade policy allows compatibility (e.g. same-major check) and bump ctx.appVersion() accordingly during upgrades.
- 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
- Keep all service replicas on the same appVersion during rolling upgrades.
- Define an explicit appVersionValidator policy (e.g. same-major) and bump ctx.appVersion() on format-relevant changes.
- Check the log's appVersion in deployment preflight before starting a new service version.
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
- mark file major version <SemanticVersion.major(version)>…
- incompatible app version
- mark file ( ) major version does not match software
- name + " cannot be negative: value=" + value
- ControlSession.RESPONSE_NOT_CONNECTED_MSG + ": " + session
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)