{"record":{"id":"cb07ea1810ed9af3","repo":"hyperledger/fabric","slug":"nil-chaincodeid-in-header-extension","errorCode":null,"errorMessage":"nil ChaincodeId in header extension","messagePattern":"nil ChaincodeId in header extension","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/committer/txvalidator/v14/vscc_validator.go","lineNumber":88,"sourceCode":"\t/* obtain the list of namespaces we're writing stuff to;\n\t   at first, we establish a few facts about this invocation:\n\t   1) which namespaces does it write to?\n\t   2) does it write to LSCC's namespace?\n\t   3) does it write to any cc that cannot be invoked? */\n\twritesToLSCC := false\n\twritesToNonInvokableSCC := false\n\trespPayload, err := protoutil.GetActionFromEnvelope(envBytes)\n\tif err != nil {\n\t\treturn peer.TxValidationCode_BAD_RESPONSE_PAYLOAD, errors.WithMessage(err, \"GetActionFromEnvelope failed\")\n\t}\n\ttxRWSet := &rwsetutil.TxRwSet{}\n\tif err = txRWSet.FromProtoBytes(respPayload.Results); err != nil {\n\t\treturn peer.TxValidationCode_BAD_RWSET, errors.WithMessage(err, \"txRWSet.FromProtoBytes failed\")\n\t}\n\n\t// Verify the header extension and response payload contain the ChaincodeId\n\tif hdrExt.ChaincodeId == nil {\n\t\treturn peer.TxValidationCode_INVALID_OTHER_REASON, errors.New(\"nil ChaincodeId in header extension\")\n\t}\n\n\tif respPayload.ChaincodeId == nil {\n\t\treturn peer.TxValidationCode_INVALID_OTHER_REASON, errors.New(\"nil ChaincodeId in ChaincodeAction\")\n\t}\n\n\t// get name and version of the cc we invoked\n\tccID := hdrExt.ChaincodeId.Name\n\tccVer := respPayload.ChaincodeId.Version\n\n\t// sanity check on ccID\n\tif ccID == \"\" {\n\t\terr = errors.New(\"invalid chaincode ID\")\n\t\tlogger.Errorf(\"%+v\", err)\n\t\treturn peer.TxValidationCode_INVALID_OTHER_REASON, err\n\t}\n\tif ccID != respPayload.ChaincodeId.Name {\n\t\terr = errors.Errorf(\"inconsistent ccid info (%s/%s)\", ccID, respPayload.ChaincodeId.Name)","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/committer/txvalidator/v14/vscc_validator.go#L70-L106","documentation":"After unmarshalling the header extension, VSCCValidateTx found that hdrExt.ChaincodeId is nil, meaning the transaction header's ChaincodeHeaderExtension does not carry a ChaincodeID. VSCC needs this ID to identify which chaincode the transaction invokes and returns TxValidationCode_INVALID_OTHER_REASON, marking the transaction invalid.","triggerScenarios":"A transaction is submitted with a ChaincodeHeaderExtension that omits the chaincode_id field (nil), typically because the client SDK or custom transaction builder did not set it, or the extension bytes were marshalled from an empty struct.","commonSituations":"Custom or older client SDKs constructing proposals/envelopes manually; transactions produced by tooling that serializes an empty ChaincodeHeaderExtension; corrupted headers after transport through non-Fabric middleware.","solutions":["Fix the client to always set ChaincodeId (name and version) in the ChaincodeHeaderExtension when building the transaction.","Regenerate/resubmit the transaction using a current Fabric SDK (fabric-sdk-node/java/go) rather than manual protobuf assembly.","If many such transactions appear, audit any custom proxy/service that rewrites envelopes, as it may strip the header extension."],"exampleFix":"// before\next := &peer.ChaincodeHeaderExtension{}\n// after\next := &peer.ChaincodeHeaderExtension{ChaincodeId: &peer.ChaincodeID{Name: \"mycc\", Version: \"1.0\"}}","handlingStrategy":"validation","validationCode":"ext := &peer.ChaincodeHeaderExtension{}\nif err := proto.Unmarshal(hdr.Extension, ext); err != nil || ext.ChaincodeId == nil || ext.ChaincodeId.Name == \"\" {\n    return errors.New(\"header extension must contain a named ChaincodeId before submission\")\n}","typeGuard":"func hasChaincodeId(ext *peer.ChaincodeHeaderExtension) bool {\n\treturn ext != nil && ext.ChaincodeId != nil && ext.ChaincodeId.Name != \"\"\n}","tryCatchPattern":"if hdrExt.ChaincodeId == nil {\n    logger.Warnf(\"tx rejected: nil ChaincodeId in header extension\")\n    return peer.TxValidationCode_INVALID_OTHER_REASON, nil\n}","preventionTips":["Never serialize an empty ChaincodeHeaderExtension into a proposal header.","Set chaincode name/version via SDK APIs, not raw protobuf fields.","Add a client-side pre-submission check that header extension carries a ChaincodeId."],"tags":["fabric","transaction-validation","missing-chaincode-id"],"backgroundTag":"invalid-transaction-header","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"}