{"record":{"id":"b6932f2da25fa005","repo":"hyperledger/fabric","slug":"error-decoding-varint-with-proto-buffer","errorCode":null,"errorMessage":"error decoding varint with proto.Buffer","messagePattern":"error decoding varint with proto\\.Buffer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/ledger/blkstorage/protobuf_util.go","lineNumber":30,"sourceCode":")\n\n// buffer provides a wrapper on top of proto.Buffer.\n// The purpose of this wrapper is to get to know the current position in the []byte\ntype buffer struct {\n\tbuf      []byte\n\tposition int\n}\n\n// newBuffer constructs a new instance of Buffer\nfunc newBuffer(b []byte) *buffer {\n\treturn &buffer{b, 0}\n}\n\n// DecodeVarint wraps the actual method and updates the position\nfunc (b *buffer) DecodeVarint() (uint64, error) {\n\tv, n := protowire.ConsumeVarint(b.buf[b.position:])\n\tif n < 0 {\n\t\treturn 0, errors.Wrap(protowire.ParseError(n), \"error decoding varint with proto.Buffer\")\n\t}\n\tb.position += n\n\treturn v, nil\n}\n\n// DecodeRawBytes wraps the actual method and updates the position\nfunc (b *buffer) DecodeRawBytes(alloc bool) ([]byte, error) {\n\tv, n := protowire.ConsumeBytes(b.buf[b.position:])\n\tif n < 0 {\n\t\treturn nil, errors.Wrap(protowire.ParseError(n), \"error decoding raw bytes with proto.Buffer\")\n\t}\n\tb.position += n\n\tif alloc {\n\t\tv = append([]byte(nil), v...)\n\t}\n\treturn v, nil\n}\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/blkstorage/protobuf_util.go#L12-L48","documentation":"The buffer type in blkstorage wraps protobuf wire decoding. DecodeVarint consumes a varint from the remaining bytes using protowire.ConsumeVarint; if the bytes are not a valid varint (malformed encoding, >64 bits, or truncated), the parse error is wrapped as \"error decoding varint with proto.Buffer\". Callers use it to walk protobuf-serialized block fields directly.","triggerScenarios":"extractHeader, extractData, extractMetadata, or TestBuffer invoked on corrupted/truncated bytes: a partial block record in the block file (crash during append), a manually edited file, zero-length or empty envelope, or bytes whose leading varint field key is malformed.","commonSituations":"Reading a block file damaged by an unclean shutdown or disk corruption, restoring a ledger file from an incomplete backup, index/segment files out of sync with block files, or feeding non-protobuf bytes into the extract helpers.","solutions":["Identify which block/file offset produced the bad bytes (the extract helper's caller) and check the block file for truncation; roll back or re-fetch the ledger from peers.","Restore the ledger directory from a valid snapshot/backup or rebuild by resetting the ledger and resyncing from orderer/peers.","If constructing bytes yourself, verify the protobuf wire format is valid (complete varint, field key) before calling DecodeVarint."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if len(buf) == 0 {\n    return errors.New(\"empty block bytes\")\n}\nif _, n := protowire.ConsumeVarint(buf); n < 0 {\n    return fmt.Errorf(\"not valid protobuf wire data: %v\", protowire.ParseError(n))\n}","typeGuard":null,"tryCatchPattern":"v, err := b.DecodeVarint()\nif err != nil {\n    var perr error\n    if errors.As(err, &perr) || errors.Is(err, os.ErrInvalid) {\n        return fmt.Errorf(\"corrupt block record: %w\", err)\n    }\n    return err\n}","preventionTips":["Shut down peers cleanly; avoid killing processes mid block-file append.","Copy ledger directories only while the peer is stopped.","Verify integrity of backups/snapshots before restoring them.","Monitor block file integrity and re-sync ledgers from peers on detection of corruption."],"tags":["protobuf","corruption","ledger"],"backgroundTag":"protobuf-decode-failure","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"}