{"record":{"id":"02fefecdf3db399a","repo":"apache/cassandra","slug":"ballot-file-corrupted","errorCode":null,"errorMessage":"Ballot file corrupted","messagePattern":"Ballot file corrupted","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/paxos/uncommitted/PaxosBallotTracker.java","lineNumber":113,"sourceCode":"        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    }\n\n    public synchronized void flush() throws IOException\n    {\n        File file = new File(directory, TMP_FNAME);\n        deleteIfExists(file);\n\n        try(SequentialWriter writer = new SequentialWriter(file, FINISH_ON_CLOSE))\n        {","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/paxos/uncommitted/PaxosBallotTracker.java#L95-L131","documentation":"After reading the two ballots from the ballot file, PaxosBallotTracker validates that the reader is at EOF and that the computed CRC32 matches the stored checksum. 'Ballot file corrupted' (IOException) means the file is truncated, has trailing bytes, or its contents don't match the checksum.","triggerScenarios":"Power loss or crash mid-write leaving a partially written ballot file; disk corruption; manual editing or truncation of the file; a file written by an incompatible version with same version id but different layout.","commonSituations":"Host crash/OOM-kill without clean shutdown, failing disks, restores from partial backups, or copying data directories while the node was running.","solutions":["Stop the node and delete the corrupt ballot file so the tracker recreates it from current paxos state","Verify disk health (smartctl/filesystem check) if corruption recurs","Restore data directories only from consistent backups taken with the node stopped or via snapshots","Take the file's checksum failure to the mailing list/JIRA if it reproduces across restarts"],"exampleFix":"// before\n# node fails: Ballot file corrupted\n// after\n$ nodetool stop\n$ rm /var/lib/cassandra/data/system/...-paxos_ballot.bin\n$ restart node","handlingStrategy":"try-catch","validationCode":"// integrity pre-check: size and CRC of the ballot file\nFile f = ballotFile;\nif (!f.exists() || f.length() != expectedFileLength) { /* treat as missing/corrupt */ }","typeGuard":null,"tryCatchPattern":"try { tracker = PaxosBallotTracker.load(dir); } catch (IOException e) { if (e.getMessage().equals(\"Ballot file corrupted\")) { Files.delete(dir.resolve(BALLOT_FILE)); tracker = PaxosBallotTracker.load(dir); } else throw e; }","preventionTips":["Ensure clean shutdowns; avoid hard power-offs/OOM kills","Use filesystems/disks with journaling or ECC","Copy data directories only from snapshots or stopped nodes","Monitor logs for repeated corruption to catch failing hardware"],"tags":["io","corruption","checksum"],"backgroundTag":"checksum-mismatch","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}