{"record":{"id":"51e1397223702d21","repo":"apache/cassandra","slug":"unsupported-ballot-file-version-version","errorCode":null,"errorMessage":"Unsupported ballot file version: ${version}","messagePattern":"Unsupported ballot file version: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/paxos/uncommitted/PaxosBallotTracker.java","lineNumber":105,"sourceCode":"    {\n        logger.info(\"truncating paxos ballot metadata in {}\", directory);\n        deleteIfExists(new File(directory, TMP_FNAME));\n        deleteIfExists(new File(directory, FNAME));\n    }\n\n    public static PaxosBallotTracker load(File directory) throws IOException\n    {\n        deleteIfExists(new File(directory, TMP_FNAME));\n\n        File file = new File(directory, FNAME);\n        if (!file.exists())\n            return new PaxosBallotTracker(directory, Ballot.none(), Ballot.none());\n\n        try (RandomAccessReader reader = RandomAccessReader.open(file))\n        {\n            int version = reader.readInt();\n            if (version != FILE_VERSION)\n                throw new IOException(\"Unsupported ballot file version: \" + version);\n\n            byte[] bytes = new byte[16];\n            CRC32 crc = crc32();\n            Ballot highBallot = deserializeBallot(reader, crc, bytes);\n            Ballot lowBallot = deserializeBallot(reader, crc, bytes);\n            int checksum = Integer.reverseBytes(reader.readInt());\n            if (!reader.isEOF() || (int) crc.getValue() != checksum)\n                throw new IOException(\"Ballot file corrupted\");\n\n            return new PaxosBallotTracker(directory, highBallot, lowBallot);\n        }\n    }\n\n    private static void deleteIfExists(File file)\n    {\n        if (file.exists())\n            file.delete();\n    }","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/paxos/uncommitted/PaxosBallotTracker.java#L87-L123","documentation":"PaxosBallotTracker persists high/low paxos ballots to a per-directory ballot file stamped with a FILE_VERSION. On load it throws IOException 'Unsupported ballot file version' when the file's version integer differs from the version this build writes — typically a file from a different Cassandra version or a corrupt/garbage first 4 bytes.","triggerScenarios":"Downgrading or upgrading Cassandra across versions that changed the ballot file format; a truncated or zero-filled ballot file left by a crash; the file being written by a different (patched) implementation.","commonSituations":"Rolling upgrades/downgrades where old ballot files remain in the data directories; restoring data dirs from backups taken with a different version; disk corruption.","solutions":["Stop the node and delete the ballot file (it is rebuilt from current paxos state; safe while no in-flight CAS relies on it — prefer deleting only when the directory is for a dropped/unsupported state)","Confirm the running Cassandra version matches the version that wrote the files; complete a rolling upgrade/downgrade consistently","Check disk/filesystem health if the version bytes look corrupted","If caused by downgrade, use the officially supported downgrade procedure which handles state files"],"exampleFix":"// before\ncassandra$ cp -r /old/data /data   # old-version ballot files mixed in\n// after\ncassandra$ rm /data/*/paxos_ballot*   # or matching ballot tracker files\n$ .build/build-jars.sh -s && restart node","handlingStrategy":"validation","validationCode":"// check the ballot file's version int before starting Cassandra\ntry (DataInputStream in = new DataInputStream(new FileInputStream(ballotFile))) {\n    int v = Integer.reverseBytes(in.readInt());\n    if (v != expectedFileVersion) { /* move file aside or confirm upgrade/downgrade path */ }\n}","typeGuard":null,"tryCatchPattern":"try { PaxosBallotTracker.load(dir); } catch (IOException e) { if (e.getMessage().startsWith(\"Unsupported ballot file version\")) { /* remove/rotate file, reload */ } throw e; }","preventionTips":["Never mix data directories across incompatible Cassandra versions","Use the supported upgrade/downgrade procedure","Back up ballot files only from the same version that will read them","Watch for crash-truncated files after unclean shutdowns"],"tags":["io","versioning","paxos"],"backgroundTag":"unsupported-config-value","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}