{"record":{"id":"2d78b16e53080e1e","repo":"aeron-io/aeron","slug":"incompatible-version-semanticversion-tostring-ctx-appversion","errorCode":null,"errorMessage":"incompatible version: <SemanticVersion.toString(ctx.appVersion())> log=<SemanticVersion.toString(appVersion)>","messagePattern":"incompatible version: <SemanticVersion\\.toString\\(ctx\\.appVersion\\(\\)\\)> log=<SemanticVersion\\.toString\\(appVersion\\)>","errorType":"exception","errorClass":"AgentTerminationException","httpStatus":null,"severity":"critical","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/service/ClusteredServiceAgent.java","lineNumber":597,"sourceCode":"        executeAction(action, logPosition, leadershipTermId, flags);\n    }\n\n    void onNewLeadershipTermEvent(\n        final long leadershipTermId,\n        final long logPosition,\n        final long timestamp,\n        final long termBaseLogPosition,\n        final int leaderMemberId,\n        final int logSessionId,\n        final TimeUnit timeUnit,\n        final int appVersion)\n    {\n        if (!ctx.appVersionValidator().isVersionCompatible(ctx.appVersion(), appVersion))\n        {\n            ctx.countedErrorHandler().onError(new ClusterException(\n                \"incompatible version: \" + SemanticVersion.toString(ctx.appVersion()) +\n                \" log=\" + SemanticVersion.toString(appVersion)));\n            throw new AgentTerminationException();\n        }\n\n        sessionMessageHeaderEncoder.leadershipTermId(leadershipTermId);\n        this.logPosition = logPosition;\n        clusterTime = timestamp;\n        this.timeUnit = timeUnit;\n\n        service.onNewLeadershipTermEvent(\n            leadershipTermId,\n            logPosition,\n            timestamp,\n            termBaseLogPosition,\n            leaderMemberId,\n            logSessionId,\n            timeUnit,\n            appVersion);\n    }\n","sourceCodeStart":579,"sourceCodeEnd":615,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/service/ClusteredServiceAgent.java#L579-L615","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nctx.appVersion(SemanticVersion.compose(1, 0, 0)); // log is 2.0.0\n// after\n// either match the log\nctx.appVersion(SemanticVersion.compose(2, 0, 0));\n// or relax the validator\nctx.appVersionValidator((current, log) -> SemanticVersion.major(current) == SemanticVersion.major(log));","handlingStrategy":"validation","validationCode":"// java: validate versions before starting the service container\nint logVersion = readLogAppVersion(clusterDir); // from the log header / recovery plan\nif (!ctx.appVersionValidator().isVersionCompatible(ctx.appVersion(), logVersion)) {\n    throw new IllegalStateException(\"service appVersion \" + SemanticVersion.toString(ctx.appVersion()) +\n        \" incompatible with log \" + SemanticVersion.toString(logVersion));\n}","typeGuard":null,"tryCatchPattern":"try {\n    serviceContainer.start();\n} catch (AgentTerminationException e) {\n    // often preceded by \"incompatible version\" in the error log;\n    // stop, fix appVersion or redeploy the matching binary, then restart\n}","preventionTips":["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."],"tags":["java","versioning","compatibility","cluster"],"backgroundTag":"incompatible-source-type","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}