{"record":{"id":"1e49fa55e6b1c9e2","repo":"hyperledger/fabric","slug":"number-of-consumed-bytes-from-decodevarint-is-inva","errorCode":null,"errorMessage":"number of consumed bytes from DecodeVarint is invalid, expected 1, but got %d","messagePattern":"number of consumed bytes from DecodeVarint is invalid, expected 1, but got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/ledger/util/util.go","lineNumber":64,"sourceCode":"\t\tpanic(fmt.Errorf(\"[]sizeBytes should not be more than one byte because the max number it needs to hold is 8. size=%d\", size))\n\t}\n\tencodedBytes := make([]byte, size+1)\n\tencodedBytes[0] = sizeBytes[0]\n\tcopy(encodedBytes[1:], bytes[startingIndex:])\n\treturn encodedBytes\n}\n\n// DecodeOrderPreservingVarUint64 decodes the number from the bytes obtained from method 'EncodeOrderPreservingVarUint64'.\n// It returns the decoded number, the number of bytes that are consumed in the process, and an error if the input bytes are invalid.\nfunc DecodeOrderPreservingVarUint64(bytes []byte) (uint64, int, error) {\n\ts, numBytes := protowire.ConsumeVarint(bytes)\n\tif numBytes < 0 {\n\t\ts, numBytes = 0, 0\n\t}\n\n\tswitch {\n\tcase numBytes != 1:\n\t\treturn 0, 0, errors.Errorf(\"number of consumed bytes from DecodeVarint is invalid, expected 1, but got %d\", numBytes)\n\tcase s > 8:\n\t\treturn 0, 0, errors.Errorf(\"decoded size from DecodeVarint is invalid, expected <=8, but got %d\", s)\n\tcase int(s) > len(bytes)-1:\n\t\treturn 0, 0, errors.Errorf(\"decoded size (%d) from DecodeVarint is more than available bytes (%d)\", s, len(bytes)-1)\n\tdefault:\n\t\t// no error\n\t\tsize := int(s)\n\t\tdecodedBytes := make([]byte, 8)\n\t\tcopy(decodedBytes[8-size:], bytes[1:size+1])\n\t\tnumBytesConsumed := size + 1\n\t\treturn binary.BigEndian.Uint64(decodedBytes), numBytesConsumed, nil\n\t}\n}\n","sourceCodeStart":46,"sourceCodeEnd":78,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/util/util.go#L46-L78","documentation":"DecodeOrderPreservingVarUint64 expects its input to be an order-preserving encoded uint64: exactly one size byte followed by the payload. proto.DecodeVarint must consume exactly 1 byte for that size prefix; if it consumes 0 or more than 1, the input is not valid order-preserving encoding and this error is returned.","triggerScenarios":"Calling DecodeOrderPreservingVarUint64 (via retrieveTxID, retrieveBlockNum, NewHeightFromBytes) on bytes that were not produced by EncodeOrderPreservingVarUint64 — e.g. empty input, a first byte >= 0x80 (multi-byte varint), or raw big-endian/protobuf-encoded integers.","commonSituations":"Reading composite keys written by a different encoder version; decoding a key with the wrong offset (skipping or including extra prefix bytes); hand-crafted keys in tests (TestDecodingBadInputBytes); interpreting another field as the numeric portion of a key.","solutions":["Verify the bytes were created with EncodeOrderPreservingVarUint64 and that you are decoding from the correct offset in the composite key","Check key-encoding version compatibility between writer and reader of the ledger data","Validate input length >= 1 and first byte < 0x80 before decoding","Dump the raw key bytes (hex) and confirm the layout matches the expected composite-key scheme"],"exampleFix":"// before\nblockNum, _, err := util.DecodeOrderPreservingVarUint64(rawKey) // rawKey includes namespace prefix\n// after\nif len(rawKey) == 0 || rawKey[0] >= 0x80 {\n\treturn fmt.Errorf(\"not an order-preserving encoded uint64\")\n}\nblockNum, _, err := util.DecodeOrderPreservingVarUint64(rawKey)","handlingStrategy":"validation","validationCode":"func canDecode(buf []byte) bool {\n\tif len(buf) == 0 { return false }\n\treturn buf[0] < 0x80 // DecodeVarint must consume exactly 1 size byte\n}","typeGuard":"func isOrderPreservingEncoded(b []byte) bool {\n\treturn len(b) > 0 && b[0] >= 1 && b[0] <= 8 && len(b) >= int(b[0])+1\n}","tryCatchPattern":"v, n, err := util.DecodeOrderPreservingVarUint64(bytes)\nif err != nil {\n\tif strings.Contains(err.Error(), \"number of consumed bytes\") {\n\t\tlog.Errorf(\"input is not order-preserving encoded: % x\", bytes)\n\t}\n\treturn err\n}","preventionTips":["Only decode bytes produced by EncodeOrderPreservingVarUint64","Slice composite keys to the exact numeric portion before decoding","Keep key-encoding logic in one shared helper across writer/reader","Hex-dump failing keys when debugging version mismatches"],"tags":["encoding","varint","deserialization","ledger"],"backgroundTag":"invalid-varint-encoding","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"}