hyperledger/fabric · error
nil ChaincodeId in header extension
Error message
nil ChaincodeId in header extension
What it means
The v20 plugin dispatcher validates that both the header extension and the ChaincodeAction response payload carry a ChaincodeId before extracting name/version for validation. When the transaction's header extension has a nil ChaincodeId, the transaction is structurally malformed and is rejected with INVALID_OTHER_REASON. This guards against transactions that don't identify which chaincode they invoke.
Source
Thrown at core/committer/txvalidator/v20/plugindispatcher/dispatcher.go:130
// get header extensions so we have the chaincode ID
hdrExt, err := protoutil.UnmarshalChaincodeHeaderExtension(chdr.Extension)
if err != nil {
return peer.TxValidationCode_BAD_HEADER_EXTENSION, err
}
/* obtain the list of namespaces we're writing to */
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_CHAINCODE, 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
- Fix the client to always set ChaincodeId in the proposal header extension (use a maintained SDK)
- Trace the offending transaction via peer logs/txId and inspect the envelope with configtxlator/inspect tools
- Reject malformed proposals at the gateway/orderer before they reach blocks
- Update SDK/Fabric versions if a known serialization bug produced nil ChaincodeId
Example fix
// before: manually built proposal missing ChaincodeId
const hdrExt = new HeaderExt(); hdrExt.ChaincodeId = null;
// after
const hdrExt = new HeaderExt(); hdrExt.ChaincodeId = {name: 'mycc', version: '1.0'}; Defensive patterns
Strategy: validation
Validate before calling
// client-side pre-check before signing/submitting
if (!proposal.getHeader().getExtension().chaincodeId) throw new Error('missing ChaincodeId in header extension'); Type guard
function hasChaincodeId(hdrExt) {
return !!hdrExt && !!hdrExt.chaincodeId && !!hdrExt.chaincodeId.name;
} Try / catch
try { await gateway.submit(tx); } catch (e) {
if (String(e).includes('nil ChaincodeId in header extension')) { /* rebuild proposal via SDK, do not retry same envelope */ }
} Prevention
- Build proposals only through maintained SDKs
- Never submit raw/hand-crafted envelopes in production
- Validate envelopes with configtxlator before submission
When it happens
Trigger: Dispatch (VSCC validation for the v20 tx validator plugin) parses a TxRWSet and inspects hdrExt.ChaincodeId — a proposal header extension without ChaincodeId reaches validation, e.g. a malformed or hand-crafted envelope.
Common situations: Buggy or low-level client SDK usage constructing proposals without ChaincodeId; malicious/fuzzed transaction submission; corrupted envelope bytes on the ordering path.
Related errors
- nil ChaincodeId in ChaincodeAction
- chaincode %s attempted to write to the namespace of a system
- chaincode %s:%s/%s didn't match %s:%s/%s in lscc
- committing an invocation of cc %s is illegal
- nil ledger instance
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/3a7b31d96d26de62.
Report an issue: GitHub.