{"record":{"id":"145fdf42463d9d7b","repo":"clockworklabs/SpacetimeDB","slug":"no-valid-commit-found-in-index-up-to-key-candida","errorCode":null,"errorMessage":"No valid commit found in index up to key: {candidate_last_key}","messagePattern":"No valid commit found in index up to key: (.+?)","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/commitlog/src/segment.rs","lineNumber":754,"sourceCode":"                        },\n                        size_in_bytes: byte_offset + commit.size_in_bytes,\n                        max_epoch: commit.epoch,\n                        max_commit_offset: commit.tx_range.start,\n                        max_commit: Some(commit),\n                    });\n                }\n\n                // `TxOffset` at `byte_offset` is not valid, so try with previous entry\n                Err(_) => {\n                    candidate_last_key = key.saturating_sub(1);\n                    if candidate_last_key == 0 {\n                        break;\n                    }\n                }\n            }\n        }\n\n        Err(io::Error::new(\n            ErrorKind::InvalidData,\n            format!(\"No valid commit found in index up to key: {candidate_last_key}\"),\n        ))\n    }\n\n    /// Validates and decodes a commit at `byte_offset` in the segment.\n    ///\n    /// # Returns\n    /// * `Ok(commit::Metadata)` - If a valid commit is found with matching transaction offset\n    /// * `Err` - If commit can't be decoded or has mismatched transaction offset\n    fn validate_commit_at_offset<R: io::Read + io::Seek>(\n        reader: &mut R,\n        tx_offset: TxOffset,\n        byte_offset: u64,\n    ) -> io::Result<commit::Metadata> {\n        reader.seek(SeekFrom::Start(byte_offset))?;\n        let commit = commit::Metadata::extract(reader)?\n            .ok_or_else(|| io::Error::new(ErrorKind::InvalidData, \"failed to decode commit\"))?;","sourceCodeStart":736,"sourceCodeEnd":772,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/3653d2ed498fddbd83b7062aa6bf8970e18635ec/crates/commitlog/src/segment.rs#L736-L772","documentation":"The index-seek path walks offset-index entries backwards from the requested transaction offset, validating each candidate commit against segment data. If every candidate key down to candidate_last_key fails to validate (reaching key 0), it gives up with io::ErrorKind::InvalidData 'No valid commit found in index up to key: N'. The index has no entry consistent with the segment.","triggerScenarios":"An offset index wholly stale relative to its segment (e.g. restored from a different generation); seeking a transaction offset older than anything the index can validate; a segment whose early records were corrupted so every candidate fails.","commonSituations":"Partial restores mixing segment and index files from different points in time; index never rebuilt after a prior corruption event; seeking to very old offsets for audit/backfill reads.","solutions":["Delete the offset index files and reopen the log to force a rebuild from segment data","Read by scanning the segment sequentially instead of using the index for the problematic offset","Verify segment and index files come from the same backup generation","If the offset genuinely predates the segment, request a lower segment offset instead"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":"fn is_index_exhausted(err: &io::Error) -> bool {\n    err.kind() == io::ErrorKind::InvalidData && err.to_string().contains(\"No valid commit found in index\")\n}","tryCatchPattern":"match reader.seek_tx(offset) {\n    Ok(pos) => Ok(pos),\n    Err(e) if is_index_exhausted(&e) => {\n        // drop the index, rescan the segment from its start\n        let _ = std::fs::remove_file(index_path);\n        reader.rescan_segment()\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Expose and schedule an index-rebuild maintenance step after restores","Validate that segment and index files in a restored directory share the same generation","Prefer scan-based reads for very old offsets instead of forcing index seeks"],"tags":["rust","commitlog","offset-index","seek","invalid-data"],"backgroundTag":"index-corruption","analyzedSha":"3653d2ed498fddbd83b7062aa6bf8970e18635ec","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}