hyperledger/fabric · error

failed to create snapshot from MemoryStorage: %s

Error message

failed to create snapshot from MemoryStorage: %s

What it means

TakeSnapshot requests a snapshot at index i from the in-memory raft MemoryStorage (ram.CreateSnapshot). MemoryStorage rejects the request (e.g. the index is out of range of its raft log, or an existing snapshot at that index already has conflicting data), and the error is wrapped with this message.

Source

Thrown at orderer/consensus/etcdraft/storage.go:303

	if err := rs.snap.SaveSnap(snap); err != nil {
		return errors.Errorf("failed to save snapshot to disk: %s", err)
	}

	rs.lg.Debugf("Releasing lock to wal files prior to %d", snap.GetMetadata().GetIndex())
	if err := rs.wal.ReleaseLockTo(snap.GetMetadata().GetIndex()); err != nil {
		return err
	}

	return nil
}

// TakeSnapshot takes a snapshot at index i from MemoryStorage, and persists it to wal and disk.
func (rs *RaftStorage) TakeSnapshot(i uint64, cs *raftpb.ConfState, data []byte) error {
	rs.lg.Debugf("Creating snapshot at index %d from MemoryStorage", i)
	snap, err := rs.ram.CreateSnapshot(i, cs, data)
	if err != nil {
		return errors.Errorf("failed to create snapshot from MemoryStorage: %s", err)
	}

	if err = rs.saveSnap(snap); err != nil {
		return err
	}

	rs.snapshotIndex = append(rs.snapshotIndex, snap.GetMetadata().GetIndex())

	// Keep some entries in memory for slow followers to catchup
	if i > rs.SnapshotCatchUpEntries {
		compacti := i - rs.SnapshotCatchUpEntries
		rs.lg.Debugf("Purging in-memory raft entries prior to %d", compacti)
		if err = rs.ram.Compact(compacti); err != nil {
			if err == raft.ErrCompacted {
				rs.lg.Warnf("Raft entries prior to %d are already purged", compacti)
			} else {
				rs.lg.Fatalf("Failed to purge raft entries: %s", err)
			}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the orderer log for the wrapped underlying error (snapshot out of date vs out-of-range index)
  2. Verify the snapshot index logic in the node's apply loop — ensure each index is snapshotted exactly once and after it is committed
  3. Restart the node if in-memory state and disk state diverged
  4. Report/pin the fabric version; if reproducible at steady state, check for known etcdraft bugs in your Hyperledger Fabric release

Example fix

// before
snap, err := rs.ram.CreateSnapshot(i, cs, data)
if err != nil {
	return errors.Errorf("failed to create snapshot from MemoryStorage: %s", err)
}
// after
evaluator := func() error { return rs.TakeSnapshot(i, cs, data) }
if err := evaluator(); err != nil {
	lg.Warnf("snapshot at index %d skipped: %s", i, err) // do not crash on duplicate snapshot request
}
Defensive patterns

Strategy: try-catch

Try / catch

if err := storage.TakeSnapshot(i, cs, data); err != nil {
	var snapOutOfDate bool
	if strings.Contains(err.Error(), "ErrSnapOutOfDate") || strings.Contains(err.Error(), "snapshot out of date") {
		snapOutOfDate = true // duplicate/superseded snapshot request — safe to skip
	}
	if !snapOutOfDate {
		return err
	}
	lg.Warnf("snapshot at index %d already superseded, skipping", i)
}

Prevention

When it happens

Trigger: takeSnapshot called with an index i that MemoryStorage cannot snapshot: i is greater than the last applied/compacted state or i <= an already existing snapshot's index (ErrSnapOutOfDate), or ConfState/data inconsistent with the log.

Common situations: Bug or race in the caller computing the snapshot index (e.g. double snapshot request for the same index); node replaying/refreshing state where the in-memory log was already compacted; mis-tuned SizePerSnapshot causing snapshot triggers at invalid indices.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/3acfd82d682d5265. Report an issue: GitHub.