hyperledger/fabric · error
attempting to deploy a system chaincode %s/%s
Error message
attempting to deploy a system chaincode %s/%s
What it means
The endorser's callChaincode path handles lscc (lifecycle system chaincode) deploy/upgrade invocations, and user proposals must never target a system chaincode directly. If the ChaincodeSpec's chaincode name is a registered system CC, the proposal is rejected as a simulation failure.
Source
Thrown at core/endorser/endorser.go:155
// ----- BEGIN - SECTION THAT MAY NEED TO BE DONE IN LSCC ------
// if this a call to deploy a chaincode, We need a mechanism
// to pass TxSimulator into LSCC. Till that is worked out this
// special code does the actual deploy, upgrade here so as to collect
// all state under one TxSimulator
//
// NOTE that if there's an error all simulation, including the chaincode
// table changes in lscc will be thrown away
cds, err := protoutil.UnmarshalChaincodeDeploymentSpec(input.Args[2])
if err != nil {
e.Metrics.SimulationFailure.With(meterLabels...).Add(1)
return nil, nil, err
}
// this should not be a system chaincode
if e.Support.IsSysCC(cds.ChaincodeSpec.ChaincodeId.Name) {
e.Metrics.SimulationFailure.With(meterLabels...).Add(1)
return nil, nil, errors.Errorf("attempting to deploy a system chaincode %s/%s", cds.ChaincodeSpec.ChaincodeId.Name, txParams.ChannelID)
}
if len(cds.CodePackage) != 0 {
e.Metrics.SimulationFailure.With(meterLabels...).Add(1)
return nil, nil, errors.Errorf("lscc upgrade/deploy should not include a code packages")
}
_, _, err = e.Support.ExecuteLegacyInit(txParams, cds.ChaincodeSpec.ChaincodeId.Name, cds.ChaincodeSpec.ChaincodeId.Version, cds.ChaincodeSpec.Input)
if err != nil {
// increment the failure to indicate instantion/upgrade failures
meterLabels = []string{
"channel", txParams.ChannelID,
"chaincode", cds.ChaincodeSpec.ChaincodeId.Name,
}
e.Metrics.InitFailed.With(meterLabels...).Add(1)
return nil, nil, err
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Use the new lifecycle (_lifecycle) CLI/SDK flow instead of invoking lscc directly
- Rename the target chaincode in the proposal to a user (application) chaincode
- If querying a system CC is intended, use the appropriate query path/channel rather than a deploy proposal
Example fix
// before ccName := "lscc" // deploy via system CC // after ccName := "mycc" // deploy via _lifecycle approve/commit flow
Defensive patterns
Strategy: validation
Validate before calling
sysCCs := map[string]bool{"lscc":true,"qscc":true,"cscc":true,"escc":true,"vscc":true,"_lifecycle":true}
if sysCCs[spec.ChaincodeId.Name] {
return errors.New("cannot deploy a system chaincode")
} Prevention
- Never target system chaincodes in deploy/upgrade proposals
- Migrate legacy lscc invocations to the _lifecycle flow
- Keep a list of reserved system CC names in client tooling
When it happens
Trigger: Submitting a transaction proposal whose ChaincodeSpec.ChaincodeId.Name is a system chaincode (e.g. 'lscc', 'qscc', 'cscc', 'escc', 'vscc') through the endorser's deploy/upgrade path.
Common situations: Clients built against old Fabric APIs that invoked lscc directly to deploy chaincodes; tooling/scripts from Fabric 1.x used on newer lifecycle; typos targeting system CCs.
Related errors
- invalid channel-less operation
- lscc upgrade/deploy should not include a code packages
- Private data is forbidden to be used in instantiate
- failed listing installed chaincodes
- failed to parse collection config
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/721c4d8c3283a0ee.
Report an issue: GitHub.