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

  1. Populate ChaincodeSpec.ChaincodeId with &pb.ChaincodeID{Name: <ccname>} (and Version/Path if needed) before building the proposal.
  2. Use the SDK's proposal builder which fills ChaincodeID from the invoke arguments instead of manual protobuf assembly.
  3. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/d5149adeab642155. Report an issue: GitHub.