{"record":{"id":"1410293476b4f000","repo":"hyperledger/fabric","slug":"unexpected-error-while-marshaling-txidindexvalprot","errorCode":null,"errorMessage":"unexpected error while marshaling TxIDIndexValProto message","messagePattern":"unexpected error while marshaling TxIDIndexValProto message","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/ledger/blkstorage/blockindex.go","lineNumber":122,"sourceCode":"\tif index.isAttributeIndexed(IndexableAttrBlockNum) {\n\t\tbatch.Put(constructBlockNumKey(blkNum), flpBytes)\n\t}\n\n\t// Index3 Used to find a transaction by its transaction id\n\tif index.isAttributeIndexed(IndexableAttrTxID) {\n\t\tfor i, txoffset := range txOffsets {\n\t\t\ttxFlp := newFileLocationPointer(flp.fileSuffixNum, flp.offset, txoffset.loc)\n\t\t\tlogger.Debugf(\"Adding txLoc [%s] for tx ID: [%s] to txid-index\", txFlp, txoffset.txID)\n\t\t\ttxFlpBytes := txFlp.marshal()\n\n\t\t\tindexVal := &TxIDIndexValue{\n\t\t\t\tBlkLocation:      flpBytes,\n\t\t\t\tTxLocation:       txFlpBytes,\n\t\t\t\tTxValidationCode: int32(txsfltr.Flag(i)),\n\t\t\t}\n\t\t\tindexValBytes, err := proto.Marshal(indexVal)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrap(err, \"unexpected error while marshaling TxIDIndexValProto message\")\n\t\t\t}\n\t\t\tbatch.Put(\n\t\t\t\tconstructTxIDKey(txoffset.txID, blkNum, uint64(i)),\n\t\t\t\tindexValBytes,\n\t\t\t)\n\t\t}\n\t}\n\n\t// Index4 - Store BlockNumTranNum will be used to query history data\n\tif index.isAttributeIndexed(IndexableAttrBlockNumTranNum) {\n\t\tfor i, txoffset := range txOffsets {\n\t\t\ttxFlp := newFileLocationPointer(flp.fileSuffixNum, flp.offset, txoffset.loc)\n\t\t\tlogger.Debugf(\"Adding txLoc [%s] for tx number:[%d] ID: [%s] to blockNumTranNum index\", txFlp, i, txoffset.txID)\n\t\t\ttxFlpBytes := txFlp.marshal()\n\t\t\tbatch.Put(constructBlockNumTranNumKey(blkNum, uint64(i)), txFlpBytes)\n\t\t}\n\t}\n","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/blkstorage/blockindex.go#L104-L140","documentation":"Thrown in blockindex.indexBlock when proto.Marshal fails on a TxIDIndexValProto message built for the transaction-ID index. Protobuf marshal of a generated, validly-populated message practically never fails, so this is treated as 'unexpected' and indicates an internal invariant break (nil message, invalid proto definition/registry mismatch).","triggerScenarios":"indexBlock (invoked from addBlock or syncIndex) while indexing transactions: only if the TxIDIndexValProto instance is nil or the proto message/registry is inconsistent (mismatched generated code vs runtime protobuf library, malformed proto descriptors).","commonSituations":"Custom builds where protoc-generated pb.go files were regenerated with an incompatible protoc/protobuf-go version; binary patches to the ledger package; corrupted Go module cache producing stale generated code.","solutions":["Read the wrapped cause beneath this message for the actual marshal error and identify which message fails.","Rebuild with the pinned protobuf/gogo-protobuf versions from go.mod (go mod tidy / go mod download; clear module cache if suspect).","Regenerate the proto types (protoc-gen-gogo) with the same generator versions the project uses instead of hand-editing generated code.","If it reproduces on one specific block, capture the block and file an issue; the block may contain data that trips the indexer (e.g. nil tx payload paths)."],"exampleFix":"// before: mismatched generated code after upgrading protobuf runtime\n// ERROR: unexpected error while marshaling TxIDIndexValProto message\n// after:\ngo mod tidy\ngo build ./...  // ensure pb.go regenerated with project's protoc-gen-gogo version","handlingStrategy":"try-catch","validationCode":"// Go: smoke-test marshal of the index value type before processing production blocks\nfunc marshalOK(v *proto.TxIDIndexValProto) error {\n\tif v == nil {\n\t\treturn errors.New(\"nil index value\")\n\t}\n\t_, err := proto.Marshal(v)\n\treturn err\n}","typeGuard":null,"tryCatchPattern":"// Go: log the wrapped cause with block/tx identifiers before failing the batch\nif err := indexBlock(block); err != nil {\n\tif strings.Contains(err.Error(), \"marshaling TxIDIndexValProto\") {\n\t\tlogger.Errorf(\"index marshal failed for block %d: %+v\", block.Header.Number, errors.Cause(err))\n\t}\n\treturn err\n}","preventionTips":["Do not override protobuf/gogo-protobuf versions away from the go.mod pins.","Regenerate *.pb.go only with the project's generator versions.","Keep go.sum/ module cache integrity (GOFLAGS=-mod=mod, verify modules).","Test block indexing in CI with real channel payloads after dependency upgrades."],"tags":["protobuf","serialization","index","ledger"],"backgroundTag":"protobuf-marshal-failed","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"}