hyperledger/fabric · error
chaincode event chaincode id does not match chaincode action
Error message
chaincode event chaincode id does not match chaincode action chaincode id
What it means
During Dispatch validation, the unmarshaled ChaincodeEvent's ChaincodeId does not equal the chaincode ID from the header extension (ccID). Fabric throws this because an event claiming to come from a different chaincode than the executing transaction is inconsistent (spoofing or bug) and invalidates the tx.
Source
Thrown at core/committer/txvalidator/v20/plugindispatcher/dispatcher.go:167
logger.Errorf("%+v", err)
return peer.TxValidationCode_INVALID_CHAINCODE, err
}
// sanity check on ccver
if ccVer == "" {
err = errors.New("invalid chaincode version")
logger.Errorf("%+v", err)
return peer.TxValidationCode_INVALID_CHAINCODE, err
}
wrNamespace := map[string]bool{}
wrNamespace[ccID] = true
if respPayload.Events != nil {
ccEvent := &peer.ChaincodeEvent{}
if err = proto.Unmarshal(respPayload.Events, ccEvent); err != nil {
return peer.TxValidationCode_INVALID_OTHER_REASON, errors.Wrapf(err, "invalid chaincode event")
}
if ccEvent.ChaincodeId != ccID {
return peer.TxValidationCode_INVALID_OTHER_REASON, errors.Errorf("chaincode event chaincode id does not match chaincode action chaincode id")
}
}
namespaces := make(map[string]struct{})
for _, ns := range txRWSet.NsRwSets {
// check to make sure there is no duplicate namespace in txRWSet
if _, ok := namespaces[ns.NameSpace]; ok {
logger.Errorf("duplicate namespace '%s' in txRWSet", ns.NameSpace)
return peer.TxValidationCode_ILLEGAL_WRITESET,
errors.Errorf("duplicate namespace '%s' in txRWSet", ns.NameSpace)
}
namespaces[ns.NameSpace] = struct{}{}
if v.txWritesToNamespace(ns) {
wrNamespace[ns.NameSpace] = true
}
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Fix the chaincode so events are emitted through shim.SetEvent, letting the shim/endorser stamp the correct ChaincodeId instead of hard-coding it.
- Audit shared chaincode code for stale hard-coded chaincode names in events.
- Regenerate the failing transaction after the chaincode fix.
- If malicious, reject the tx (the validator already does) and investigate the submitter.
Example fix
// before
ccEvent := &peer.ChaincodeEvent{ChaincodeId: "othercc", EventName: "e"}
// after
stub.SetEvent("e", payload) // ChaincodeId derived from executing chaincode Defensive patterns
Strategy: validation
Validate before calling
// before endorsing, verify event attribution
if (ccEvent.chaincodeId && ccEvent.chaincodeId !== invokingChaincodeId) { throw new Error('event chaincode id does not match action'); } Type guard
function eventBelongsToChaincode(ev, ccId) { return !ev?.chaincodeId || ev.chaincodeId === ccId; } Try / catch
try { validate(tx); } catch (err) { if (/event chaincode id does not match/.test(err.message)) { /* reject tx; investigate emitting chaincode */ } else { throw err; } } Prevention
- Emit events via shim.SetEvent so ChaincodeId is stamped automatically.
- Avoid hard-coding chaincode names in event code.
- Review shared chaincode libraries for stale IDs.
- Treat mismatches as possible spoofing.
When it happens
Trigger: Chaincode emits an event whose ChaincodeId field (set by the shim/endorser) differs from the chaincode named in the proposal header — e.g. one chaincode fabricates an event attributed to another, or headers/payloads are mixed.
Common situations: Cross-chaincode event spoofing attempts; copy-pasted event-emitting code in shared chaincode repos where the ID constant was not updated; event created through custom serialization that hard-coded another cc ID.
Related errors
- invalid chaincode event
- '%s' not equal <newest|oldest|config|(number)>
- unmarshalling block: %s
- specified --channelID %s does not match channel ID %s in con
- unmarshalling envelope: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/f9baa8a9913ae5e9.
Report an issue: GitHub.