{"record":{"id":"4ee51889747e7ea7","repo":"hyperledger/fabric","slug":"error-unmarshalling-chaincodeheaderextension","errorCode":null,"errorMessage":"error unmarshalling ChaincodeHeaderExtension","messagePattern":"error unmarshalling ChaincodeHeaderExtension","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/committer/txvalidator/v14/vscc_validator.go","lineNumber":50,"sourceCode":"\n// newVSCCValidator creates new vscc validator\nfunc newVSCCValidator(channelID string, cr ChannelResources, pluginValidator *PluginValidator) *VsccValidatorImpl {\n\treturn &VsccValidatorImpl{\n\t\tchannelID:       channelID,\n\t\tcr:              cr,\n\t\tpluginValidator: pluginValidator,\n\t}\n}\n\nfunc getChaincodeHeaderExtension(hdr *common.Header) (*peer.ChaincodeHeaderExtension, error) {\n\tchdr, err := protoutil.UnmarshalChannelHeader(hdr.ChannelHeader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tchaincodeHdrExt := &peer.ChaincodeHeaderExtension{}\n\terr = proto.Unmarshal(chdr.Extension, chaincodeHdrExt)\n\treturn chaincodeHdrExt, errors.Wrap(err, \"error unmarshalling ChaincodeHeaderExtension\")\n}\n\n// VSCCValidateTx executes vscc validation for transaction\nfunc (v *VsccValidatorImpl) VSCCValidateTx(seq int, payload *common.Payload, envBytes []byte, block *common.Block) (peer.TxValidationCode, error) {\n\tchainID := v.channelID\n\tlogger.Debugf(\"[%s] VSCCValidateTx starts for bytes %p\", chainID, envBytes)\n\n\t// get header extensions so we have the chaincode ID\n\thdrExt, err := getChaincodeHeaderExtension(payload.Header)\n\tif err != nil {\n\t\treturn peer.TxValidationCode_BAD_HEADER_EXTENSION, err\n\t}\n\n\t// get channel header\n\tchdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)\n\tif err != nil {\n\t\treturn peer.TxValidationCode_BAD_CHANNEL_HEADER, err\n\t}","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/committer/txvalidator/v14/vscc_validator.go#L32-L68","documentation":"getChaincodeHeaderExtension failed to proto-unmarshal the payload header's Extension bytes into a peer.ChaincodeHeaderExtension. This means the ChaincodeHeaderExtension field of the transaction's header (chdr.Extension) is corrupt, truncated, or not a valid serialized ChaincodeHeaderExtension. The peer wraps the underlying unmarshal error with this message and VSCCValidateTx aborts validation of the transaction.","triggerScenarios":"A transaction envelope whose payload header's Extension field contains bytes that do not decode as a ChaincodeHeaderExtension protobuf (e.g. empty/corrupt extension, wrong message type serialized there, or bits flipped in transit/storage). Raised inside getChaincodeHeaderExtension, called from VSCCValidateTx during block validation.","commonSituations":"Malformed or tampered transactions submitted by a misbehaving client or SDK; transactions built by hand-crafted protobuf code that puts the wrong message in the header extension; corrupted blocks read from storage or received from an orderer.","solutions":["Inspect the offending transaction's payload header extension bytes and verify they serialize a peer.ChaincodeHeaderExtension (use protoc --decode_raw).","Fix the client SDK / transaction-construction code so it marshals ChaincodeHeaderExtension correctly into the header extension field.","If the transaction is corrupt, remove it and resubmit; a corrupted block on disk may require refetching the block from the orderer.","Confirm protobuf runtime versions on the client match the Fabric proto definitions being used."],"exampleFix":"// before: hand-built header extension bytes\nhdr.Extension = someArbitraryBytes\n// after\nhdrExt := &peer.ChaincodeHeaderExtension{ChaincodeId: &peer.ChaincodeID{Name: ccName}}\nraw, _ := proto.Marshal(hdrExt)\nhdr.Extension = raw","handlingStrategy":"validation","validationCode":"if len(envelope.Payload) == 0 || len(payload.Header.Extension) == 0 {\n    return errors.New(\"transaction header extension missing; cannot validate\")\n}\next := &peer.ChaincodeHeaderExtension{}\nif err := proto.Unmarshal(payload.Header.Extension, ext); err != nil {\n    return fmt.Errorf(\"malformed ChaincodeHeaderExtension: %w\", err)\n}","typeGuard":"func isValidHeaderExtension(b []byte) bool {\n\text := &peer.ChaincodeHeaderExtension{}\n\treturn proto.Unmarshal(b, ext) == nil && ext.ChaincodeId != nil\n}","tryCatchPattern":"result, err := v.getChaincodeHeaderExtension(chdr)\nif err != nil {\n    logger.Warnf(\"skipping tx: %v\", err)\n    return peer.TxValidationCode_BAD_PAYLOAD, nil\n}","preventionTips":["Always build envelopes with a maintained Fabric SDK instead of manual protobuf assembly.","Verify tx bytes with protoc --decode_raw when constructing transactions by hand.","Keep client proto definitions in sync with the Fabric version on the network."],"tags":["fabric","transaction-validation","protobuf-unmarshal"],"backgroundTag":"protobuf-unmarshal-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"}