hyperledger/fabric · error
ChaincodeHeaderExtension.ChaincodeId is nil
Error message
ChaincodeHeaderExtension.ChaincodeId is nil
What it means
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.
Source
Thrown at core/endorser/msgvalidation.go:69
}
chdr, err := protoutil.UnmarshalChannelHeader(hdr.ChannelHeader)
if err != nil {
return nil, err
}
shdr, err := protoutil.UnmarshalSignatureHeader(hdr.SignatureHeader)
if err != nil {
return nil, err
}
chaincodeHdrExt, err := protoutil.UnmarshalChaincodeHeaderExtension(chdr.Extension)
if err != nil {
return nil, err
}
if chaincodeHdrExt.ChaincodeId == nil {
return nil, errors.Errorf("ChaincodeHeaderExtension.ChaincodeId is nil")
}
if chaincodeHdrExt.ChaincodeId.Name == "" {
return nil, errors.Errorf("ChaincodeHeaderExtension.ChaincodeId.Name is empty")
}
cpp, err := protoutil.UnmarshalChaincodeProposalPayload(prop.Payload)
if err != nil {
return nil, err
}
cis, err := protoutil.UnmarshalChaincodeInvocationSpec(cpp.Input)
if err != nil {
return nil, err
}
if cis.ChaincodeSpec == nil {
return nil, errors.Errorf("chaincode invocation spec did not contain chaincode spec")View on GitHub (pinned to 2736b63f8f)
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
Example fix
// before
ext := &pb.ChaincodeHeaderExtension{PayloadVisibility: []byte("hash")} // no ChaincodeId
// after
ext := &pb.ChaincodeHeaderExtension{ChaincodeId: &pb.ChaincodeID{Name: "mycc", Version: "1.0"}} Defensive patterns
Strategy: validation
Validate before calling
ext := &pb.ChaincodeHeaderExtension{ChaincodeId: &pb.ChaincodeID{Name: ccName, Version: ccVer}}
if ext.ChaincodeId == nil || ext.ChaincodeId.Name == "" {
return errors.New("proposal extension must set ChaincodeId.Name")
} Type guard
func hasChaincodeId(ext *pb.ChaincodeHeaderExtension) bool {
return ext != nil && ext.ChaincodeId != nil
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ChaincodeHeaderExtension.ChaincodeId.Name is empty
- chaincode invocation spec did not contain chaincode spec
- chaincode input did not contain any input
- empty proposal bytes
- Failing extracting proposal during channelless check policy
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/625934200918d050.
Report an issue: GitHub.