{"record":{"id":"79cd4d85dac14933","repo":"hyperledger/fabric","slug":"error-in-decoding-varint-bytes-v","errorCode":null,"errorMessage":"Error in decoding varint bytes [%#v]","messagePattern":"Error in decoding varint bytes \\[%#v\\]","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"common/ledger/blkstorage/block_stream.go","lineNumber":115,"sourceCode":"\t// Peek 8 or smaller number of bytes (if remaining bytes are less than 8)\n\t// Assumption is that a block size would be small enough to be represented in 8 bytes varint\n\tpeekBytes := 8\n\tif remainingBytes < int64(peekBytes) {\n\t\tpeekBytes = int(remainingBytes)\n\t\tmoreContentAvailable = false\n\t}\n\tlogger.Debugf(\"Remaining bytes=[%d], Going to peek [%d] bytes\", remainingBytes, peekBytes)\n\tif lenBytes, err = s.reader.Peek(peekBytes); err != nil {\n\t\treturn nil, nil, errors.Wrapf(err, \"error peeking [%d] bytes from block file\", peekBytes)\n\t}\n\tlength, n := protowire.ConsumeVarint(lenBytes)\n\tif n <= 0 {\n\t\t// proto.DecodeVarint did not consume any byte at all which means that the bytes\n\t\t// representing the size of the block are partial bytes\n\t\tif !moreContentAvailable {\n\t\t\treturn nil, nil, ErrUnexpectedEndOfBlockfile\n\t\t}\n\t\tpanic(errors.Errorf(\"Error in decoding varint bytes [%#v]\", lenBytes))\n\t}\n\tbytesExpected := int64(n) + int64(length)\n\tif bytesExpected > remainingBytes {\n\t\tlogger.Debugf(\"At least [%d] bytes expected. Remaining bytes = [%d]. Returning with error [%s]\",\n\t\t\tbytesExpected, remainingBytes, ErrUnexpectedEndOfBlockfile)\n\t\treturn nil, nil, ErrUnexpectedEndOfBlockfile\n\t}\n\t// skip the bytes representing the block size\n\tif _, err = s.reader.Discard(n); err != nil {\n\t\treturn nil, nil, errors.Wrapf(err, \"error discarding [%d] bytes\", n)\n\t}\n\tblockBytes := make([]byte, length)\n\tif _, err = io.ReadAtLeast(s.reader, blockBytes, int(length)); err != nil {\n\t\tlogger.Errorf(\"Error reading [%d] bytes from file number [%d], error: %s\", length, s.fileNum, err)\n\t\treturn nil, nil, errors.Wrapf(err, \"error reading [%d] bytes from file number [%d]\", length, s.fileNum)\n\t}\n\tblockPlacementInfo := &blockPlacementInfo{\n\t\tfileNum:          s.fileNum,","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/blkstorage/block_stream.go#L97-L133","documentation":"A panic raised when protowire.ConsumeVarint returns n <= 0 on the peeked length-prefix bytes while moreContentAvailable is still true. This means the bytes at the current offset are not a valid varint at all — corruption, not a torn tail (a torn tail with no more content returns ErrUnexpectedEndOfBlockfile instead). The code cannot make any progress, so it panics.","triggerScenarios":"nextBlockBytesAndPlacementInfo peeks bytes, ConsumeVarint fails (n<=0), AND moreContentAvailable==true — i.e. remaining bytes >= peekBytes but they do not decode as a varint length prefix.","commonSituations":"Bit rot / disk corruption of the blockfile; writes to the file from an unexpected process; reading a non-blockfile or a file with a wrong offset (corrupt checkpoint); manually edited or patched ledger files.","solutions":["Treat as file corruption: run ledger integrity checks and restore the blockfile from backup or re-sync from other peers/orderers","Verify no external process wrote to the ledger directory","Check the offset source — a corrupt checkpoint can point mid-block; rebuild the checkpoint/rollback","Check storage health (SMART, dmesg) for bit rot"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"func looksLikeVarintPrefix(b []byte) bool {\n    _, n := protowire.ConsumeVarint(b)\n    return n > 0\n}","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        logger.Errorf(\"blockfile corruption: %v\", r)\n        triggerLedgerRebuild()\n    }\n}()","preventionTips":["Use ECC/scrubbed storage; monitor SMART for bit rot","Restrict ledger directory write access to the peer user only","Verify integrity after any manual restore of ledger files","Keep backups/snapshots of ledger data"],"tags":["fabric","ledger","panic","corruption","varint"],"backgroundTag":"ledger-data-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"}