hyperledger/fabric · info
already at height of %d
Error message
already at height of %d
What it means
Raised in Synchronizer.synchronize when the local ledger height (startHeight) is already greater than or equal to the computed target height derived from remote peers' heights. This is not a fault: it means the node has nothing to replicate — it is as up-to-date as (or ahead of) the cluster members it probed. Sync then falls back to serving state from the local ledger.
Source
Thrown at orderer/consensus/smartbft/synchronizer.go:108
if err != nil {
return nil, errors.Wrap(err, "cannot get HeightsByEndpoints")
}
s.Logger.Infof("HeightsByEndpoints: %v", heightByEndpoint)
if len(heightByEndpoint) == 0 {
return nil, errors.New("no cluster members to synchronize with")
}
var heights []uint64
for _, value := range heightByEndpoint {
heights = append(heights, value)
}
targetHeight := s.computeTargetHeight(heights)
startHeight := s.Support.Height()
if startHeight >= targetHeight {
return nil, errors.Errorf("already at height of %d", targetHeight)
}
targetSeq := targetHeight - 1
seq := startHeight
var blocksFetched int
s.Logger.Debugf("Will fetch sequences [%d-%d]", seq, targetSeq)
var lastPulledBlock *cb.Block
for seq <= targetSeq {
block := blockPuller.PullBlock(seq)
if block == nil {
s.Logger.Debugf("Failed to fetch block [%d] from cluster", seq)
break
}
if protoutil.IsConfigBlock(block) {
s.Support.WriteConfigBlock(block, nil)View on GitHub (pinned to 2736b63f8f)
Solutions
- If the node is healthy this is expected — verify the local ledger height matches the cluster and ignore
- Check why remote peers report low heights: are most cluster members down? Bring up a quorum
- If this node is erroneously ahead (restored backup), reconcile with the actual cluster ledger; do NOT truncate the ledger manually without operator procedures
- Ensure enough endpoints are reachable so computeTargetHeight sees the true maximum cluster height
Defensive patterns
Strategy: type-guard
Validate before calling
// Compare local height to remote heights before triggering sync
localHeight := support.Height()
remoteHeights := probeHeights(consenters) // via Deliver service
if maxOf(remoteHeights) <= localHeight {
// node is already caught up; skip synchronization entirely
} Try / catch
// Treat 'already at height' as success: check result height instead of error
resp := synchronizer.Sync()
if resp.Latest.Height >= expectedHeight {
// healthy caught-up state; no action needed
} Prevention
- Treat this error as benign info, not a fault, in monitoring/alerting
- Ensure a quorum of up-to-date peers is online so targetHeight reflects the true cluster height
- Avoid restoring ledgers from backups newer than the live cluster
- Log and compare local vs remote heights routinely
When it happens
Trigger: Synchronizer.Sync -> synchronize runs, HeightsByEndpoint probing succeeds, computeTargetHeight(heights) <= s.Support.Height(). Happens when this orderer is already caught up, when remote peers are lagging/behind (making targetHeight lower), or when computeTargetHeight picks a low height (e.g. f+1-th highest height with few reachable peers).
Common situations: Healthy caught-up orderer whose node still calls Sync (benign, logged as a warning); most cluster members are offline so the probe only sees laggard peers; after restoring from backup this node is ahead of the live cluster; asymmetry after network partition heals.
Related errors
- already at target height of %d
- pending config does not match calculated expected config
- failed creating a new BFTChain
- cannot get HeightsByEndpoints
- no cluster members to synchronize with
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/47da41b25461a3ab.
Report an issue: GitHub.