canopy-network/canopy · error · ErrStoreGet

missing commit id at height %d

Error message

missing commit id at height %d

What it means

To rebuild state at the target version, Rollback reads the stored commit ID for that height via the commit-ID index. If the index entry is absent or empty, the rollback cannot proceed safely, so it fails with this error identifying the height.

Source

Thrown at store/store.go:355

	if targetVersion > currentVersion {
		return ErrCommitDB(fmt.Errorf("rollback target height %d exceeds current height %d", targetVersion, currentVersion))
	}
	if targetVersion == currentVersion {
		return nil
	}

	snapshot := s.db.NewSnapshot()
	defer snapshot.Close()

	// Ensure the target commit exists so we can repoint the latest commit id.
	targetReader := NewVersionedStore(snapshot, nil, targetVersion)
	targetTx := NewTxn(targetReader, nil, nil, false, false, true)
	targetCommitID, err := targetTx.Get(s.commitIDKey(targetVersion))
	if err != nil {
		return err
	}
	if len(targetCommitID) == 0 {
		return ErrStoreGet(fmt.Errorf("missing commit id at height %d", targetVersion))
	}

	batch := s.db.NewBatch()
	defer batch.Close()

	minVersion := targetVersion + 1
	affectedStateKeys := make(map[string][]byte)
	for _, prefix := range [][]byte{
		historicStatePrefix,
		indexerPrefix,
		stateCommitIDPrefix,
	} {
		if err = s.pruneVersionWindow(
			snapshot,
			batch,
			prefix,
			minVersion,
			currentVersion,

View on GitHub (pinned to ee8197d91d)

Solutions

  1. Choose a target height that actually has a committed block (verify against block/commit records)
  2. Inspect the commit-ID keyspace to confirm which heights have commit IDs before rolling back
  3. Restore from a consistent checkpoint/backup if the commit-ID index is corrupted

Example fix

// before
store.Rollback(targetHeight) // no commit at targetHeight
// after
if !hasCommitIDAt(store, targetHeight) {
    targetHeight = lastCommittedHeightBelow(store, targetHeight)
}
store.Rollback(targetHeight)
Defensive patterns

Strategy: validation

Validate before calling

reader := store.NewReaderAt(currentVersion) // or snapshot
if _, err := reader.Get(store.CommitIDKey(targetVersion)); err != nil || len(v)==0 {
    return fmt.Errorf("no commit id at height %d; pick a committed height", targetVersion)
}

Try / catch

if err := st.Rollback(h); err != nil {
    if strings.Contains(err.Error(), "missing commit id") {
        // height has no committed block; fall back to nearest committed height
        return st.Rollback(nearestCommittedHeight(h))
    }
    return err
}

Prevention

When it happens

Trigger: Calling Rollback(targetVersion) where the commitIDKey(targetVersion) record is missing — e.g. the height never had a committed block, the index was corrupted/truncated by a prior partial rollback, or an empty value was written at that key.

Common situations: Rolling back to a height that was skipped (no block committed at that height); a database that was restored from a checkpoint missing older commit records; corruption from an aborted previous maintenance run.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of canopy-network/canopy@ee8197d91d (2026-09-06). Data as JSON: /api/errors/b20c1dcb87eb7fe4. Report an issue: GitHub.