{"record":{"id":"625934200918d050","repo":"hyperledger/fabric","slug":"chaincodeheaderextension-chaincodeid-is-nil","errorCode":null,"errorMessage":"ChaincodeHeaderExtension.ChaincodeId is nil","messagePattern":"ChaincodeHeaderExtension\\.ChaincodeId is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/endorser/msgvalidation.go","lineNumber":69,"sourceCode":"\t}\n\n\tchdr, err := protoutil.UnmarshalChannelHeader(hdr.ChannelHeader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tshdr, err := protoutil.UnmarshalSignatureHeader(hdr.SignatureHeader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tchaincodeHdrExt, err := protoutil.UnmarshalChaincodeHeaderExtension(chdr.Extension)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif chaincodeHdrExt.ChaincodeId == nil {\n\t\treturn nil, errors.Errorf(\"ChaincodeHeaderExtension.ChaincodeId is nil\")\n\t}\n\n\tif chaincodeHdrExt.ChaincodeId.Name == \"\" {\n\t\treturn nil, errors.Errorf(\"ChaincodeHeaderExtension.ChaincodeId.Name is empty\")\n\t}\n\n\tcpp, err := protoutil.UnmarshalChaincodeProposalPayload(prop.Payload)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcis, err := protoutil.UnmarshalChaincodeInvocationSpec(cpp.Input)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif cis.ChaincodeSpec == nil {\n\t\treturn nil, errors.Errorf(\"chaincode invocation spec did not contain chaincode spec\")","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/endorser/msgvalidation.go#L51-L87","documentation":"UnpackProposal decodes the header extension into a ChaincodeHeaderExtension via protoutil.UnmarshalChaincodeHeaderExtension. Even if unmarshaling succeeds, the resulting ChaincodeId field can be nil (e.g. extension bytes only carried a payload hash); a proposal without a chaincode ID cannot be routed, so it is rejected.","triggerScenarios":"Submitting a proposal whose ChannelHeader.Extension unmarshals to a ChaincodeHeaderExtension with ChaincodeId == nil — typically an old-style or malformed proposal extension containing only the payload hash.","commonSituations":"Clients built against Fabric 1.0-era message formats where the extension omitted ChaincodeId; hand-crafted proposals in tests/tools; corrupted or truncated header extensions.","solutions":["Build the proposal with the current SDK/protoutil so the header extension includes ChaincodeId with name and version","Regenerate the proposal if it was created by older tooling","Validate the decoded ChaincodeHeaderExtension before submitting"],"exampleFix":"// before\next := &pb.ChaincodeHeaderExtension{PayloadVisibility: []byte(\"hash\")} // no ChaincodeId\n// after\next := &pb.ChaincodeHeaderExtension{ChaincodeId: &pb.ChaincodeID{Name: \"mycc\", Version: \"1.0\"}}","handlingStrategy":"validation","validationCode":"ext := &pb.ChaincodeHeaderExtension{ChaincodeId: &pb.ChaincodeID{Name: ccName, Version: ccVer}}\nif ext.ChaincodeId == nil || ext.ChaincodeId.Name == \"\" {\n    return errors.New(\"proposal extension must set ChaincodeId.Name\")\n}","typeGuard":"func hasChaincodeId(ext *pb.ChaincodeHeaderExtension) bool {\n    return ext != nil && ext.ChaincodeId != nil\n}","tryCatchPattern":null,"preventionTips":["Always set ChaincodeId in the header extension when building proposals","Use the current SDK/protoutil constructors instead of hand-assembling headers","Validate proposals with UnpackProposal in client tests before submission"],"tags":["endorser","proposal-validation","header-extension","protobuf"],"backgroundTag":"chaincode-header-extension-invalid","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"}