{"record":{"id":"2433d24251378604","repo":"aeron-io/aeron","slug":"failed-to-find-candidateterm-entry","errorCode":null,"errorMessage":"failed to find CandidateTerm entry","messagePattern":"failed to find CandidateTerm entry","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/NodeStateFile.java","lineNumber":202,"sourceCode":"            nodeStateHeaderDecoder.sbeBlockLength(),\n            NodeStateFooterDecoder.TEMPLATE_ID,\n            buffer,\n            messageHeaderDecoder);\n\n        if (Aeron.NULL_VALUE == footerOffset)\n        {\n            throw new IllegalStateException(\"failed to find NodeStateFooter entry, file corrupt?\");\n        }\n\n        final int candidateTermOffset = scanForMessageTypeOffset(\n            nodeStateHeaderDecoder.sbeBlockLength(),\n            CandidateTermDecoder.TEMPLATE_ID,\n            buffer,\n            messageHeaderDecoder);\n\n        if (Aeron.NULL_VALUE == candidateTermOffset)\n        {\n            throw new IllegalStateException(\"failed to find CandidateTerm entry\");\n        }\n\n        candidateTermDecoder.wrapAndApplyHeader(buffer, candidateTermOffset, messageHeaderDecoder);\n    }\n\n    private static void initialiseDecodersOnCreation(\n        final MutableDirectBuffer buffer,\n        final NodeStateHeaderDecoder nodeStateHeaderDecoder,\n        final MessageHeaderDecoder messageHeaderDecoder,\n        final CandidateTermDecoder candidateTermDecoder)\n    {\n        final MessageHeaderEncoder messageHeaderEncoder = new MessageHeaderEncoder();\n\n        nodeStateHeaderDecoder.wrap(\n            buffer, 0, NodeStateHeaderDecoder.BLOCK_LENGTH, NodeStateHeaderDecoder.SCHEMA_VERSION);\n        new NodeStateHeaderEncoder()\n            .wrap(buffer, 0)\n            .version(ClusterMarkFile.SEMANTIC_VERSION);","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/NodeStateFile.java#L184-L220","documentation":"NodeStateFile.loadInitialState scans the node state file for a CandidateTerm SBE message by reading recorded offsets; the offset returned by candidateTermOffset() was Aeron.NULL_VALUE, meaning no CandidateTerm entry exists in the file. The library throws IllegalStateException because loading the initial state requires a CandidateTerm entry to decode, so the file is missing required content.","triggerScenarios":"Calling NodeStateFile.loadInitialState() (via loadDecodersAndOffsets) on a node state file that has no CandidateTerm record — e.g. the file was created empty/truncated, the CandidateTerm entry was never appended, or the file is from an older format that never wrote one.","commonSituations":"Replaying a corrupted or partially-written node-state file after a cluster crash; pointing a replica at a state file produced by a different Aeron version; manually copying or truncating cluster data directories during backup/restore.","solutions":["Verify the node state file being opened is intact and actually contains a CandidateTerm entry (check file size and that the member was a candidate at some point).","If the file was created but never initialized, recreate/initialize it through the normal cluster lifecycle instead of loading it directly.","Restore the file from a known-good backup of the cluster data directory.","Confirm the Aeron version matches the one that wrote the file; regenerate state if upgrading across versions."],"exampleFix":"// before\nfinal NodeStateFile f = new NodeStateFile(ctx); f.loadInitialState(); // throws if no entry\n// after\nif (f.hasCandidateTermEntry()) { f.loadInitialState(); } else { recreateOrRestoreStateFile(); }","handlingStrategy":"try-catch","validationCode":"if (nodeStateFile.file().length() == 0 || !hasCandidateTermEntryOnDisk(file)) { restoreFromBackup(); }","typeGuard":null,"tryCatchPattern":"try { nodeStateFile.loadInitialState(); } catch (IllegalStateException e) { restoreStateFromBackupOrRejoinCluster(); }","preventionTips":["Never hand-copy or truncate cluster data directories while the cluster is running.","Take state file copies only after a clean shutdown.","Keep the same Aeron version for reading and writing node state files."],"tags":["cluster","persistence","corrupt-file","sbe-decoding"],"backgroundTag":"record-not-found","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"}