hyperledger/fabric · error

invalid chaincode event

Error message

invalid chaincode event

What it means

Dispatch failed to protobuf-unmarshal respPayload.Events into a peer.ChaincodeEvent. The Events field of the chaincode action must be a serialized ChaincodeEvent message; Fabric wraps the unmarshal failure with 'invalid chaincode event' and marks the tx INVALID_OTHER_REASON.

Source

Thrown at core/committer/txvalidator/v20/plugindispatcher/dispatcher.go:164

	}
	if ccID != respPayload.ChaincodeId.Name {
		err = errors.Errorf("inconsistent ccid info (%s/%s)", ccID, respPayload.ChaincodeId.Name)
		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

  1. In chaincode, only pass event payloads via shim.SetEvent(name, payload); do not pre-wrap or manually marshal into ChaincodeEvent.
  2. Verify the chaincode shim version matches the peer (event wire format is proto-defined).
  3. Locate the offending chaincode from the failing tx and fix/redeploy it; re-submit the transaction.
  4. If custom serialization was applied to respPayload.Events upstream, remove it.

Example fix

// before
stub.SetEvent("myevent", protoMarshal(&peer.ChaincodeEvent{...}))
// after
stub.SetEvent("myevent", []byte(`{"k":"v"}`)) // shim handles serialization
Defensive patterns

Strategy: validation

Validate before calling

// chaincode side, before SetEvent: ensure payload is plain bytes, not a pre-marshaled ChaincodeEvent
if (typeof eventPayload !== 'string' && !(eventPayload instanceof Uint8Array)) { throw new Error('event payload must be raw bytes'); }

Try / catch

try { validate(tx); } catch (err) { if (/invalid chaincode event/.test(err.message)) { /* fix emitting chaincode, redeploy, resubmit */ } else { throw err; } }

Prevention

When it happens

Trigger: During validation, respPayload.Events is non-nil but its bytes are not a valid serialized ChaincodeEvent — produced by a chaincode emitting raw/arbitrary bytes via SetEvent, corrupted payloads, or non-standard serializers.

Common situations: Chaincode that sets an event with manually marshaled or non-ChaincodeEvent bytes; corrupted response payloads after serialization bugs; custom shims writing events in a different format.

Related errors


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