canopy-network/canopy · error · ErrCommitDB
rollback target height must be >= 1
Error message
rollback target height must be >= 1
What it means
Rollback requires a positive target height: version 0 does not exist as a rollback destination (state versions start at 1). Passing targetVersion == 0 is rejected with this error before any database work is done.
Source
Thrown at store/store.go:331
keys := make([][]byte, 0, len(s.ss.txn.ops))
for _, op := range s.ss.txn.ops {
keys = append(keys, bytes.Clone(op.key))
}
s.ss.txn.l.Unlock()
return s.Indexer.indexStateChangeKeys(version, keys)
}
// 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)View on GitHub (pinned to ee8197d91d)
Solutions
- Pass a target height >= 1, typically the last known good block height
- Check the CLI/config parsing that supplies targetVersion and guard against zero values before calling Rollback
- If the intent is 'rewind one block', compute currentVersion - 1 instead of using 0
Example fix
// before
if err := store.Rollback(targetHeight); err != nil {...} // targetHeight==0
// after
if targetHeight < 1 {
return fmt.Errorf("--height must be provided (>=1)")
}
if err := store.Rollback(targetHeight); err != nil {...} Defensive patterns
Strategy: validation
Validate before calling
if targetVersion < 1 {
return fmt.Errorf("rollback target height must be >= 1, got %d", targetVersion)
} Try / catch
if err := st.Rollback(h); err != nil {
if strings.Contains(err.Error(), "must be >= 1") {
return fmt.Errorf("invalid --height flag: must supply a block height >= 1")
}
return err
} Prevention
- Validate CLI/config height flags before invoking Rollback
- Make the height flag required (no silent zero default)
- Map 'genesis' explicitly to version 1 if that semantic is needed
When it happens
Trigger: Calling Store.Rollback(0), e.g. a misconfigured CLI flag or a variable that defaulted to zero because the target height was never parsed/loaded from config.
Common situations: Rollback command invoked with a missing --height flag defaulting to 0; a script computing target height from an unset environment variable; off-by-one logic mapping 'genesis' to version 0.
Related errors
- rollback target height %d exceeds current height %d
- 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/4da71075fe389aef.
Report an issue: GitHub.