clockworklabs/SpacetimeDB · error · io::Error

No valid commit found in index up to key

Error message

No valid commit found in index up to key: {candidate_last_key}

What it means

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.

Solutions

  1. Delete the offset index files and reopen the log to force a rebuild from segment data
  2. Read by scanning the segment sequentially instead of using the index for the problematic offset
  3. Verify segment and index files come from the same backup generation
  4. If the offset genuinely predates the segment, request a lower segment offset instead
Defensive patterns

Strategy: fallback

Type guard

fn is_index_exhausted(err: &io::Error) -> bool {
    err.kind() == io::ErrorKind::InvalidData && err.to_string().contains("No valid commit found in index")
}

Try / catch

match reader.seek_tx(offset) {
    Ok(pos) => Ok(pos),
    Err(e) if is_index_exhausted(&e) => {
        // drop the index, rescan the segment from its start
        let _ = std::fs::remove_file(index_path);
        reader.rescan_segment()
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@3653d2ed49 (2026-08-20). Data as JSON: /api/errors/145fdf42463d9d7b. Report an issue: GitHub.

Appendix: source

Thrown at crates/commitlog/src/segment.rs:754

                        },
                        size_in_bytes: byte_offset + commit.size_in_bytes,
                        max_epoch: commit.epoch,
                        max_commit_offset: commit.tx_range.start,
                        max_commit: Some(commit),
                    });
                }

                // `TxOffset` at `byte_offset` is not valid, so try with previous entry
                Err(_) => {
                    candidate_last_key = key.saturating_sub(1);
                    if candidate_last_key == 0 {
                        break;
                    }
                }
            }
        }

        Err(io::Error::new(
            ErrorKind::InvalidData,
            format!("No valid commit found in index up to key: {candidate_last_key}"),
        ))
    }

    /// Validates and decodes a commit at `byte_offset` in the segment.
    ///
    /// # Returns
    /// * `Ok(commit::Metadata)` - If a valid commit is found with matching transaction offset
    /// * `Err` - If commit can't be decoded or has mismatched transaction offset
    fn validate_commit_at_offset<R: io::Read + io::Seek>(
        reader: &mut R,
        tx_offset: TxOffset,
        byte_offset: u64,
    ) -> io::Result<commit::Metadata> {
        reader.seek(SeekFrom::Start(byte_offset))?;
        let commit = commit::Metadata::extract(reader)?
            .ok_or_else(|| io::Error::new(ErrorKind::InvalidData, "failed to decode commit"))?;

View on GitHub (pinned to 3653d2ed49)