hyperledger/fabric · error
nil ChaincodeId
Error message
nil ChaincodeId
What it means
Thrown by the endorser parser's validate() when ChaincodeID is nil while the ChaincodeID field of the ChaincodeInvocationSpec/Proposal is required. The parser needs at least a chaincode name to route and validate the transaction. A nil ChaincodeID means the proposal does not identify the target chaincode, so validation fails.
Source
Thrown at core/tx/endorser/parser.go:149
if e.Version != 0 {
return errors.Errorf("invalid version in ChannelHeader. Expected 0, got [%d]", e.Version)
}
if err := ValidateChannelID(e.ChannelID); err != nil {
return err
}
if len(e.Nonce) == 0 {
return errors.New("empty nonce")
}
if len(e.Creator) == 0 {
return errors.New("empty creator")
}
if e.ChaincodeID == nil {
return errors.New("nil ChaincodeId")
}
if e.ChaincodeID.Name == "" {
return errors.New("empty chaincode name in chaincode id")
}
// TODO FAB-16170: check proposal hash
// TODO FAB-16170: verify that txid matches the one in the header
// TODO FAB-16170: check that header in the tx action and channel header match bitwise
return nil
}
// UnmarshalEndorserTxAndValidate receives a tx.Envelope containing
// a partially unmarshalled endorser transaction and returns an EndorserTx
// instance (or an error)View on GitHub (pinned to 2736b63f8f)
Solutions
- Populate ChaincodeSpec.ChaincodeId with &pb.ChaincodeID{Name: <ccname>} (and Version/Path if needed) before building the proposal.
- Use the SDK's proposal builder which fills ChaincodeID from the invoke arguments instead of manual protobuf assembly.
- Guard before submit: if spec.ChaincodeId == nil { return error }.
Example fix
// before
spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: nil}
// after
spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "mycc"}} Defensive patterns
Strategy: validation
Validate before calling
if spec.ChaincodeId == nil { return errors.New("ChaincodeSpec.ChaincodeId must be set") } Type guard
func hasChaincodeID(spec *pb.ChaincodeSpec) bool { return spec != nil && spec.ChaincodeId != nil } Prevention
- Construct ChaincodeSpec with a named ChaincodeID in one helper used everywhere.
- Never initialize ChaincodeID structs as bare empty literals.
- Validate the full spec (Type, ChaincodeId.Name, Input) before proposal creation.
When it happens
Trigger: Submitting a chaincode proposal whose ChaincodeInvocationSpec.ChaincodeSpec.ChaincodeId is unset — e.g. constructing a ChaincodeSpec with only Type/Name missing the ChaincodeID field, or invoking a query built by hand without the ccid.
Common situations: Hand-crafted protobuf proposals in tests; SDK upgrades where ChaincodeSpec construction changed; invoking system chaincodes with partially populated specs; copying proposal templates and forgetting the Id field.
Related errors
- empty chaincode name in chaincode id
- only applicable for private data
- unknown operation type
- error reading chaincode install package at %s
- error unmarshalling ChaincodeHeaderExtension
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/d5149adeab642155.
Report an issue: GitHub.