{"record":{"id":"7ceaa0db0d22ac83","repo":"clockworklabs/SpacetimeDB","slug":"invaliddata-7ceaa0","errorCode":"InvalidData","errorMessage":"no valid commits in segment","messagePattern":"no valid commits in segment","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"critical","filePath":"crates/commitlog/src/repo/mod.rs","lineNumber":323,"sourceCode":"        .open_segment_reader(offset)\n        .map_err(|source| with_segment_context(\"opening segment for resume\", repo, offset, source))?;\n\n    // If the segment at `offset` is empty, remove it and try the previous.\n    // Return an error if no previous segment is found.\n    let len = reader\n        .segment_len()\n        .map_err(|source| with_segment_context(\"determining segment file size for resume\", repo, offset, source))?;\n    if len <= segment::Header::LEN as u64 {\n        debug!(\"repo {}: segment {} is empty\", repo, offset);\n        return Ok(ResumedSegment::Empty);\n    }\n\n    let guard_non_empty = |meta: &Metadata| match meta.tx_range.is_empty() {\n        true => Err(with_segment_context(\n            \"checking metadata\",\n            repo,\n            offset,\n            io::Error::new(io::ErrorKind::InvalidData, \"no valid commits in segment\"),\n        )),\n        false => Ok(()),\n    };\n\n    // The segment is now guaranteed to be non-empty, i.e. contain more bytes\n    // than the segment header.\n    //\n    // Traverse it to gather the `Metadata` and ensure that the segment is safe\n    // to resume, which is the case if:\n    //\n    // - it contains at least one commit\n    // - it does not contain corrupted commits\n    // - the existing segment passes the compatibility check\n    // - the existing segment's version is the same as\n    //   the one requested in `opts`\n    let offset_index = repo.get_offset_index(offset).ok();\n    let meta = match Metadata::extract(offset, &mut reader, offset_index.as_ref()) {\n        Err(error::SegmentMetadata::InvalidCommit { sofar, source }) => {","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/commitlog/src/repo/mod.rs#L305-L341","documentation":"During log open/resume (resume_segment_writer), a segment file longer than its 10-byte header was traversed but its Metadata ended with an empty transaction range: not a single complete commit could be decoded. The library refuses to resume such a segment (InvalidData) because it cannot distinguish a crash remnant (header + torn first commit) from real corruption.","triggerScenarios":"A crash after the segment header was written but before the first commit completed, leaving only partial commit bytes; truncation or bit-rot destroying the only commit in a segment; a foreign file with a valid header but garbage body.","commonSituations":"Power loss right after a segment roll; kill -9 during the very first commit; partially restored data directories.","solutions":["The segment contains zero valid commits, so nothing committed is lost: quarantine/delete the named segment file and reopen - the log recreates it","If anything downstream might have depended on that segment, restore it from a backup/replica instead of deleting","If it reproduces without any preceding crash, preserve the file and report it as a bug"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_no_valid_commits(e: &io::Error) -> bool {\n    e.kind() == io::ErrorKind::InvalidData\n        && e.to_string().contains(\"no valid commits in segment\")\n}","tryCatchPattern":"match Commitlog::open(dir, opts, None) {\n    Ok(log) => log,\n    Err(e) if is_no_valid_commits(&e) => {\n        // segment holds zero valid commits: quarantine it and retry open once\n        let path = extract_segment_path(&e); // path precedes the bracketed context\n        std::fs::rename(&path, path.with_extension(\"quarantine\"))?;\n        Commitlog::open(dir, opts, None)?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Call flush_and_sync before acknowledging offsets as committed","Crash-test the first-commit path after segment roll in CI","Keep replicas or backups so damaged segments can be restored rather than deleted"],"tags":["rust","commitlog","segment","corruption","crash-recovery","invalid-data"],"backgroundTag":"log-corruption-detected","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}