{"record":{"id":"0c38e6dff2b2adde","repo":"hyperledger/fabric","slug":"invalid-txidkey-zero-length-slice","errorCode":null,"errorMessage":"invalid txIDKey - zero-length slice","messagePattern":"invalid txIDKey - zero-length slice","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/ledger/blkstorage/blockindex.go","lineNumber":429,"sourceCode":"func constructBlockHashKey(blockHash []byte) []byte {\n\treturn append([]byte{blockHashIdxKeyPrefix}, blockHash...)\n}\n\nfunc constructTxIDKey(txID string, blkNum, txNum uint64) []byte {\n\tk := append(\n\t\t[]byte{txIDIdxKeyPrefix},\n\t\tutil.EncodeOrderPreservingVarUint64(uint64(len(txID)))...,\n\t)\n\tk = append(k, txID...)\n\tk = append(k, util.EncodeOrderPreservingVarUint64(blkNum)...)\n\treturn append(k, util.EncodeOrderPreservingVarUint64(txNum)...)\n}\n\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) {","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/blkstorage/blockindex.go#L411-L447","documentation":"retrieveTxID decodes index keys of the format prefix:len(TxID):TxID:BlkNum:TxNum. If the input slice is empty, there is nothing to decode, so the function returns this error. Callers pass raw keys from the txID index iterator, so a zero-length key indicates a corrupted or malformed iterator position.","triggerScenarios":"exportUniqueTxIDs feeding dbItr.Key() when the iterator yields an empty key, or unit-test calls (TestTxIDKeyDecodingInvalidInputs) passing empty byte slices directly.","commonSituations":"Corrupted leveldb index content yielding empty keys during iteration; tests validating decoder robustness.","solutions":["Guard callers: skip/flag empty keys returned by the iterator instead of decoding them.","If seen in production, treat the index DB as corrupted and rebuild the block index.","In code, check len(key) > 0 before calling retrieveTxID."],"exampleFix":"// before\ntxID, err := retrieveTxID(dbItr.Key())\n// after\nif len(dbItr.Key()) == 0 {\n    continue // skip empty key\n}\ntxID, err := retrieveTxID(dbItr.Key())","handlingStrategy":"validation","validationCode":"if len(encodedTxIDKey) == 0 {\n    return \"\", errors.New(\"skipping empty txID key\")\n}","typeGuard":"func isValidTxIDKey(k []byte) bool {\n    return len(k) > 0 && k[0] == txIDIdxKeyPrefix\n}","tryCatchPattern":"txID, err := retrieveTxID(key)\nif err != nil && strings.Contains(err.Error(), \"zero-length slice\") {\n    // log & skip malformed key during iteration\n    continue\n}\nif err != nil { return err }","preventionTips":["Always skip or quarantine empty iterator keys instead of decoding them blindly.","If empty keys appear in production, rebuild the index — it indicates DB corruption."],"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"}