{"record":{"id":"236bf5ed3c047b26","repo":"aeron-io/aeron","slug":"mark-file-major-version-semanticversion-major-version-does","errorCode":null,"errorMessage":"mark file major version <SemanticVersion.major(version)> does not match software: <MAJOR_VERSION>","messagePattern":"mark file major version <SemanticVersion\\.major\\(version\\)> does not match software: <MAJOR_VERSION>","errorType":"exception","errorClass":"ClusterException","httpStatus":null,"severity":"critical","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/service/ClusterMarkFile.java","lineNumber":169,"sourceCode":"        {\n            final int currentHeaderOffset = headerOffset(file);\n            final MarkFile existingMarkFile = new MarkFile(\n                file,\n                true,\n                currentHeaderOffset + MarkFileHeaderDecoder.versionEncodingOffset(),\n                currentHeaderOffset + MarkFileHeaderDecoder.activityTimestampEncodingOffset(),\n                totalFileLength,\n                timeoutMs,\n                epochClock,\n                (version) ->\n                {\n                    if (VERSION_FAILED == version)\n                    {\n                        System.err.println(\"mark file version -1 indicates error on previous startup.\");\n                    }\n                    else if (SemanticVersion.major(version) != MAJOR_VERSION)\n                    {\n                        throw new ClusterException(\"mark file major version \" + SemanticVersion.major(version) +\n                            \" does not match software: \" + MAJOR_VERSION);\n                    }\n                },\n                null);\n            final UnsafeBuffer existingBuffer = existingMarkFile.buffer();\n\n            if (0 != currentHeaderOffset)\n            {\n                headerDecoder.wrapAndApplyHeader(existingBuffer, 0, messageHeaderDecoder);\n            }\n            else\n            {\n                headerDecoder.wrap(\n                    existingBuffer, 0, MarkFileHeaderDecoder.BLOCK_LENGTH, MarkFileHeaderDecoder.SCHEMA_VERSION);\n            }\n\n            final ClusterComponentType existingType = headerDecoder.componentType();\n            if (existingType != ClusterComponentType.UNKNOWN && existingType != type)","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/service/ClusterMarkFile.java#L151-L187","documentation":"When a ClusterMarkFile already exists on disk, its header's semantic version is checked; if the major version differs from the MAJOR_VERSION the running software expects, a ClusterException is thrown. This prevents a cluster component from running against state files written by an incompatible major release of the format.","triggerScenarios":"Starting a consensus module or cluster service over a pre-existing cluster mark file (cluster-mark-0.mark etc.) whose header major version differs from the running binary's MAJOR_VERSION — e.g. after upgrading or downgrading Aeron.","commonSituations":"Aeron version upgrade without migrating/cleaning the cluster directory; rolling deployments with mixed versions; pointing a new binary at an old replay/archive directory.","solutions":["Run the same (or format-compatible) Aeron version that created the existing mark file.","If the old data is disposable, stop the cluster, back up, and delete the stale mark file from the cluster directory.","Perform a proper upgrade path: drain/stop the old version's cluster cleanly before starting the new version."],"exampleFix":"// before\n# start v1.40 binary against directory written by v1.30\n// after\n# matching versions\nmv cluster/cluster-mark-*.mark cluster/backup/  # only if state is expendable\n# or run the binary version that matches the mark file","handlingStrategy":"validation","validationCode":"// java: probe the mark file version before starting the component\ntry (ClusterMarkFile probe = new ClusterMarkFile(markFile, null, 0, epochClock, logger)) {\n    int version = probe.version();\n    if (SemanticVersion.major(version) != ClusterMarkFile.MAJOR_VERSION) {\n        throw new IllegalStateException(\"stale mark file, major=\" + SemanticVersion.major(version));\n    }\n} catch (NoSuchFileException ignore) { /* fresh start is fine */ }","typeGuard":null,"tryCatchPattern":"try {\n    startCluster();\n} catch (ClusterException e) {\n    if (e.getMessage().contains(\"mark file major version\")) {\n        // stop, archive the old mark file, or redeploy the matching version\n    }\n    throw e;\n}","preventionTips":["Pin the Aeron version across all cluster nodes; upgrade the whole cluster in a coordinated operation.","Back up the cluster directory before any version upgrade.","Never mix binaries of different major versions in the same cluster directory."],"tags":["java","versioning","compatibility","mark-file"],"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"}