{"record":{"id":"94c64bb43cbb1410","repo":"hyperledger/fabric","slug":"invalid-txidkey-x-fewer-bytes-present","errorCode":null,"errorMessage":"invalid txIDKey {%x}, fewer bytes present","messagePattern":"invalid txIDKey (.+?), fewer bytes present","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/ledger/blkstorage/blockindex.go","lineNumber":442,"sourceCode":"\n// retrieveTxID takes input an encoded txid key of the format `prefix:len(TxID):TxID:BlkNum:TxNum`\n// and returns the TxID from this\nfunc retrieveTxID(encodedTxIDKey []byte) (string, error) {\n\tif len(encodedTxIDKey) == 0 {\n\t\treturn \"\", errors.New(\"invalid txIDKey - zero-length slice\")\n\t}\n\tif encodedTxIDKey[0] != txIDIdxKeyPrefix {\n\t\treturn \"\", errors.Errorf(\"invalid txIDKey {%x} - unexpected prefix\", encodedTxIDKey)\n\t}\n\tremainingBytes := encodedTxIDKey[utf8.RuneLen(txIDIdxKeyPrefix):]\n\n\ttxIDLen, n, err := util.DecodeOrderPreservingVarUint64(remainingBytes)\n\tif err != nil {\n\t\treturn \"\", errors.WithMessagef(err, \"invalid txIDKey {%x}\", encodedTxIDKey)\n\t}\n\tremainingBytes = remainingBytes[n:]\n\tif len(remainingBytes) <= int(txIDLen) {\n\t\treturn \"\", errors.Errorf(\"invalid txIDKey {%x}, fewer bytes present\", encodedTxIDKey)\n\t}\n\treturn string(remainingBytes[:int(txIDLen)]), nil\n}\n\nfunc retrieveBlockNum(encodedTxIDKey []byte, BlkNumStartingIndex int) (uint64, error) {\n\tn, _, err := util.DecodeOrderPreservingVarUint64(encodedTxIDKey[BlkNumStartingIndex:])\n\treturn n, err\n}\n\ntype rangeScan struct {\n\tstartKey []byte\n\tstopKey  []byte\n}\n\nfunc constructTxIDRangeScan(txID string) *rangeScan {\n\tsk := append(\n\t\t[]byte{txIDIdxKeyPrefix},\n\t\tutil.EncodeOrderPreservingVarUint64(uint64(len(txID)))...,","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/blkstorage/blockindex.go#L424-L460","documentation":"After decoding the varint length of the TxID, retrieveTxID expects remaining bytes to contain TxID bytes plus BlkNum and TxNum. If the remaining byte count is <= the declared txIDLen, the key is truncated or malformed, and this error reports the hex bytes.","triggerScenarios":"Truncated or corrupted leveldb values/keys in the txID index, or hand-crafted keys where len(TxID) overstates the actual payload (as exercised in TestTxIDKeyDecodingInvalidInputs).","commonSituations":"Index corruption from partial writes, manually copied or truncated DB files, or unit tests validating decoder robustness against length mismatches.","solutions":["Treat as index corruption: stop the peer and rebuild the block index (reindex from block files or rejoin the channel).","Validate that keys are only produced by constructTxIDKey; never hand-build encoded txID keys.","Check the storage volume for truncation/partial copy issues if ledgers were migrated."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// ensure declared txID length fits the available bytes before decoding\nremaining := key[1:] // after prefix\n_, n, err := util.DecodeOrderPreservingVarUint64(remaining)\nif err != nil || n <= 0 || n >= len(remaining) {\n    return \"\", errors.Errorf(\"malformed txID key: %x\", key)\n}","typeGuard":null,"tryCatchPattern":"txID, err := retrieveTxID(key)\nif err != nil && strings.Contains(err.Error(), \"fewer bytes present\") {\n    return fmt.Errorf(\"truncated txID key %x — rebuild index: %w\", key, err)\n}\nif err != nil { return err }","preventionTips":["Treat this as index corruption in production: rebuild the block index.","Ensure ledger directories are copied only when the peer is stopped, and fully (no truncation).","Add integrity checks after ledger migration between hosts/volumes."],"tags":["ledger","blockstorage","decoding","corruption"],"backgroundTag":"invalid-index-key-format","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"}