hyperledger/fabric · error
invalid chaincode version
Error message
invalid chaincode version
What it means
The chaincode version taken from the chaincode action's response payload (respPayload.ChaincodeId.Version) is empty during Dispatch validation. The V20 validator requires both name and version to compute write namespaces and select chaincode metadata, so an empty version invalidates the tx.
Source
Thrown at core/committer/txvalidator/v20/plugindispatcher/dispatcher.go:154
// 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)
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 {View on GitHub (pinned to 2736b63f8f)
Solutions
- Regenerate the transaction with a standard peer/SDK so ChaincodeId.Version is populated from the deployed chaincode definition.
- Ensure the chaincode is properly instantiated/upgraded with a real version string (e.g. '1.0'), not empty.
- Align fabric-peer and fabric-sdk/shim versions.
- Audit custom endorsement paths for stripped Version fields.
Example fix
// before (chaincode deployment) chaincode install -n mycc -v "" // invalid // after peer chaincode install -n mycc -v 1.0
Defensive patterns
Strategy: validation
Validate before calling
if (!respPayload.chaincodeId.version) { throw new Error('chaincode version missing in response payload'); } Type guard
function hasChaincodeVersion(p) { return typeof p?.chaincodeId?.version === 'string' && p.chaincodeId.version.length > 0; } Try / catch
try { await contract.submitTransaction(...); } catch (err) { if (/invalid chaincode version/.test(err.message)) { /* redeploy with a real version and resubmit */ } else { throw err; } } Prevention
- Deploy chaincode with a non-empty version string.
- Use standard peer/SDK serialization paths.
- Keep endorser and validator code versions in sync.
- Do not strip fields when re-serializing payloads.
When it happens
Trigger: Dispatch is called and respPayload.ChaincodeId.Version == "" — typically a response payload constructed without the version field (custom/malformed endorser or client), or an old/incompatible serialization path.
Common situations: Hand-crafted or tool-generated endorsements missing ChaincodeId.Version; custom chaincode shim or modified fabric-samples code that clears the field; version skew between endorser and validator code.
Related errors
- '%s' not equal <newest|oldest|config|(number)>
- unmarshalling block: %s
- specified --channelID %s does not match channel ID %s in con
- unmarshalling envelope: %s
- specified --channelID %s does not match channel ID %s in con
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/c7bde9c703d3c70b.
Report an issue: GitHub.