{"record":{"id":"20a7fc2a406b1b64","repo":"hyperledger/fabric","slug":"failed-to-restore-persisted-raft-data-s","errorCode":null,"errorMessage":"failed to restore persisted raft data: %s","messagePattern":"failed to restore persisted raft data: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"orderer/consensus/etcdraft/chain.go","lineNumber":236,"sourceCode":"}\n\n// NewChain constructs a chain object.\nfunc NewChain(\n\tsupport consensus.ConsenterSupport,\n\topts Options,\n\tconf Configurator,\n\trpc RPC,\n\tcryptoProvider bccsp.BCCSP,\n\tf CreateBlockPuller,\n\thaltCallback func(),\n\tobserveC chan<- raft.SoftState,\n) (*Chain, error) {\n\tlg := opts.Logger.With(\"channel\", support.ChannelID(), \"node\", opts.RaftID)\n\n\tfresh := !wal.Exist(opts.WALDir)\n\tstorage, err := CreateStorage(lg, opts.WALDir, opts.SnapDir, opts.MemoryStorage)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"failed to restore persisted raft data: %s\", err)\n\t}\n\n\tif opts.SnapshotCatchUpEntries == 0 {\n\t\tstorage.SnapshotCatchUpEntries = DefaultSnapshotCatchUpEntries\n\t} else {\n\t\tstorage.SnapshotCatchUpEntries = opts.SnapshotCatchUpEntries\n\t}\n\n\tsizeLimit := opts.SnapshotIntervalSize\n\tif sizeLimit == 0 {\n\t\tsizeLimit = DefaultSnapshotIntervalSize\n\t}\n\n\t// get block number in last snapshot, if exists\n\tvar snapBlkNum uint64\n\tcc := &raftpb.ConfState{}\n\tif s := storage.Snapshot(); !raft.IsEmptySnap(s) {\n\t\tb := protoutil.UnmarshalBlockOrPanic(s.GetData())","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/chain.go#L218-L254","documentation":"During chain creation, NewChain calls CreateStorage to open the raft WAL and snapshot store. If restoring the persisted raft data fails (corrupt or unreadable WAL/snapshot files), the chain cannot start and the underlying error is wrapped with 'failed to restore persisted raft data'. This guards against starting raft from inconsistent persistence that could fork the channel.","triggerScenarios":"HandleChain/NewChain invoked at orderer startup for a channel whose WALDir or SnapDir contains corrupted, partially-written, or incompatible etcd/wal files — CreateStorage (wal.Open + snapshot store) returns an error.","commonSituations":"Disk full during write leaving a truncated WAL segment; manual copying of WAL directories between nodes; running a newer/older etcd/raft library with an incompatible WAL format; permission problems reading WALDir/SnapDir.","solutions":["Read the wrapped %s error in the log to identify the exact WAL/snapshot failure (e.g., 'corrupt', 'permission denied').","If WAL is corrupted beyond repair, restore the channel from the latest valid snapshot or by removing the channel and re-joining from a healthy orderer (ledger will re-sync).","Check filesystem permissions on WALDir and SnapDir for the orderer process user, and confirm disk space.","Never hand-copy WAL/snap dirs between orderers; instead re-join the channel via the participation API."],"exampleFix":"// before: blindly reusing a corrupt WAL dir\n// orderer fails at startup\n\n// after: re-join channel to rebuild raft persistence\n// os -remove channel then join again:\n// curl -X POST .../participation/v1/channels -d '{...join...}'","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := CreateStorage(lg, walDir, snapDir, memStore); err != nil {\n    logger.Errorf(\"raft data corrupt: %s; re-join channel to rebuild\", err)\n    // fallback: remove and re-join the channel via participation API\n}","preventionTips":["Ensure adequate disk space and clean shutdowns for orderers","Monitor WAL/snapshot directory permissions","Never copy WAL dirs between nodes; always re-join instead"],"tags":["orderer","etcdraft","raft","wal","persistence"],"backgroundTag":"raft-wal-corruption","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}