hyperledger/fabric · error

nil ChaincodeId in header extension

Error message

nil ChaincodeId in header extension

What it means

After unmarshalling the header extension, VSCCValidateTx found that hdrExt.ChaincodeId is nil, meaning the transaction header's ChaincodeHeaderExtension does not carry a ChaincodeID. VSCC needs this ID to identify which chaincode the transaction invokes and returns TxValidationCode_INVALID_OTHER_REASON, marking the transaction invalid.

Source

Thrown at core/committer/txvalidator/v14/vscc_validator.go:88

	/* obtain the list of namespaces we're writing stuff to;
	   at first, we establish a few facts about this invocation:
	   1) which namespaces does it write to?
	   2) does it write to LSCC's namespace?
	   3) does it write to any cc that cannot be invoked? */
	writesToLSCC := false
	writesToNonInvokableSCC := false
	respPayload, err := protoutil.GetActionFromEnvelope(envBytes)
	if err != nil {
		return peer.TxValidationCode_BAD_RESPONSE_PAYLOAD, errors.WithMessage(err, "GetActionFromEnvelope failed")
	}
	txRWSet := &rwsetutil.TxRwSet{}
	if err = txRWSet.FromProtoBytes(respPayload.Results); err != nil {
		return peer.TxValidationCode_BAD_RWSET, errors.WithMessage(err, "txRWSet.FromProtoBytes failed")
	}

	// Verify the header extension and response payload contain the ChaincodeId
	if hdrExt.ChaincodeId == nil {
		return peer.TxValidationCode_INVALID_OTHER_REASON, errors.New("nil ChaincodeId in header extension")
	}

	if respPayload.ChaincodeId == nil {
		return peer.TxValidationCode_INVALID_OTHER_REASON, errors.New("nil ChaincodeId in ChaincodeAction")
	}

	// get name and version of the cc we invoked
	ccID := hdrExt.ChaincodeId.Name
	ccVer := respPayload.ChaincodeId.Version

	// sanity check on ccID
	if ccID == "" {
		err = errors.New("invalid chaincode ID")
		logger.Errorf("%+v", err)
		return peer.TxValidationCode_INVALID_OTHER_REASON, err
	}
	if ccID != respPayload.ChaincodeId.Name {
		err = errors.Errorf("inconsistent ccid info (%s/%s)", ccID, respPayload.ChaincodeId.Name)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Fix the client to always set ChaincodeId (name and version) in the ChaincodeHeaderExtension when building the transaction.
  2. Regenerate/resubmit the transaction using a current Fabric SDK (fabric-sdk-node/java/go) rather than manual protobuf assembly.
  3. If many such transactions appear, audit any custom proxy/service that rewrites envelopes, as it may strip the header extension.

Example fix

// before
ext := &peer.ChaincodeHeaderExtension{}
// after
ext := &peer.ChaincodeHeaderExtension{ChaincodeId: &peer.ChaincodeID{Name: "mycc", Version: "1.0"}}
Defensive patterns

Strategy: validation

Validate before calling

ext := &peer.ChaincodeHeaderExtension{}
if err := proto.Unmarshal(hdr.Extension, ext); err != nil || ext.ChaincodeId == nil || ext.ChaincodeId.Name == "" {
    return errors.New("header extension must contain a named ChaincodeId before submission")
}

Type guard

func hasChaincodeId(ext *peer.ChaincodeHeaderExtension) bool {
	return ext != nil && ext.ChaincodeId != nil && ext.ChaincodeId.Name != ""
}

Try / catch

if hdrExt.ChaincodeId == nil {
    logger.Warnf("tx rejected: nil ChaincodeId in header extension")
    return peer.TxValidationCode_INVALID_OTHER_REASON, nil
}

Prevention

When it happens

Trigger: A transaction is submitted with a ChaincodeHeaderExtension that omits the chaincode_id field (nil), typically because the client SDK or custom transaction builder did not set it, or the extension bytes were marshalled from an empty struct.

Common situations: Custom or older client SDKs constructing proposals/envelopes manually; transactions produced by tooling that serializes an empty ChaincodeHeaderExtension; corrupted headers after transport through non-Fabric middleware.

Related errors


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