canopy-network/canopy · error · ErrCommitDB
rollback target height %d exceeds current height %d
Error message
rollback target height %d exceeds current height %d
What it means
Rollback rewinds state to an earlier version; it cannot roll forward. If the requested targetVersion is greater than the store's current committed version, the operation is nonsensical and rejected with this error naming both heights.
Source
Thrown at store/store.go:338
// Rollback rewinds the store to a previous version (height).
//
// It removes all versioned entries above targetVersion, rebuilds the latest state
// view from historical state at targetVersion, and resets the latest commit pointer.
// NOTE: Rollback is an offline maintenance operation and must only run while the node is stopped.
func (s *Store) Rollback(targetVersion uint64) lib.ErrorI {
if s.isTxn {
return ErrCommitDB(fmt.Errorf("rollback is not supported for nested transactions"))
}
if targetVersion == 0 {
return ErrCommitDB(fmt.Errorf("rollback target height must be >= 1"))
}
s.mu.Lock()
defer s.mu.Unlock()
currentVersion := s.version
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))
}View on GitHub (pinned to ee8197d91d)
Solutions
- Query the store's current version (s.Version()) and choose a targetVersion <= that value
- If the operation already succeeded previously, no further rollback is needed — verify current height instead
- Ensure the DB you are operating on is the one the target height belongs to
Example fix
// before
store.Rollback(5000) // current height is 4200
// after
current := store.Version()
target := uint64(4000)
if target > current {
target = current // clamp or abort
}
store.Rollback(target) Defensive patterns
Strategy: validation
Validate before calling
current := st.Version()
if targetVersion > current {
return fmt.Errorf("cannot roll forward: target %d > current %d", targetVersion, current)
} Try / catch
if err := st.Rollback(h); err != nil {
if strings.Contains(err.Error(), "exceeds current height") {
log.Infof("store already at or below height %d; nothing to do", h)
return nil
}
return err
} Prevention
- Read st.Version() first and clamp/abort before calling Rollback
- Make rollback scripts idempotent (no-op when already at/below target)
- Never copy target heights from other nodes without checking this store's height
When it happens
Trigger: Calling Rollback(targetVersion) where targetVersion > s.version — e.g. after the DB was already rolled back once, or the operator supplied a height from a different (longer) chain/db.
Common situations: Re-running a rollback script twice with the same target height after the first succeeded; restoring a backup and then attempting to roll back to a height that only existed before the backup; copy-pasting a height from another node.
Related errors
- rollback target height must be >= 1
- rollback is not supported for nested transactions
- missing commit id at height %d
- event not found
- quorum certificate not found
AI-assisted analysis of canopy-network/canopy@ee8197d91d (2026-09-06).
Data as JSON: /api/errors/0d91ab887665ff43.
Report an issue: GitHub.