hyperledger/fabric · error
Private data is forbidden to be used in instantiate
Error message
Private data is forbidden to be used in instantiate
What it means
During simulation, if the transaction produced private-data writes (PvtSimulationResults) and the target chaincode is lscc, the endorser rejects the proposal: collection configuration in instantiate could not be stored outside LSCC at the time, so private data in instantiate is forbidden.
Source
Thrown at core/endorser/endorser.go:212
return res, nil, ccevent, nil, nil
}
// Note, this is a little goofy, as if there is private data, Done() gets called
// early, so this is invoked multiple times, but that is how the code worked before
// this change, so, should be safe. Long term, let's move the Done up to the create.
defer txParams.TXSimulator.Done()
simResult, err := txParams.TXSimulator.GetTxSimulationResults()
if err != nil {
e.Metrics.SimulationFailure.With(meterLabels...).Add(1)
return nil, nil, nil, nil, err
}
if simResult.PvtSimulationResults != nil {
if chaincodeName == "lscc" {
// TODO: remove once we can store collection configuration outside of LSCC
e.Metrics.SimulationFailure.With(meterLabels...).Add(1)
return nil, nil, nil, nil, errors.New("Private data is forbidden to be used in instantiate")
}
pvtDataWithConfig, err := AssemblePvtRWSet(txParams.ChannelID, simResult.PvtSimulationResults, txParams.TXSimulator, e.Support.GetDeployedCCInfoProvider())
// To read collection config need to read collection updates before
// releasing the lock, hence txParams.TXSimulator.Done() moved down here
txParams.TXSimulator.Done()
if err != nil {
e.Metrics.SimulationFailure.With(meterLabels...).Add(1)
return nil, nil, nil, nil, errors.WithMessage(err, "failed to obtain collections config")
}
endorsedAt, err := e.Support.GetLedgerHeight(txParams.ChannelID)
if err != nil {
e.Metrics.SimulationFailure.With(meterLabels...).Add(1)
return nil, nil, nil, nil, errors.WithMessage(err, fmt.Sprintf("failed to obtain ledger height for channel '%s'", txParams.ChannelID))
}
// Add ledger height at which transaction was endorsed,
// `endorsedAt` is obtained from the block storage and at times this could be 'endorsement Height + 1'.
// However, since we use this height only to select the configuration (3rd parameter in distributePrivateData) andView on GitHub (pinned to 2736b63f8f)
Solutions
- Use the new lifecycle (_lifecycle) approve/commit flow where collection configuration is passed to commit
- Remove private-data/collection definitions from the legacy instantiate path
- Update tooling so collections are configured outside lscc
Example fix
// before peer chaincode instantiate -C mychannel -n mycc --collections-config collections.json ... // after peer lifecycle chaincode approveformyorg ... --collections-config collections.json peer lifecycle chaincode commit -C mychannel -n mycc ...
Defensive patterns
Strategy: validation
Validate before calling
if chaincodeName == "lscc" && simResult.PvtSimulationResults != nil {
return errors.New("use _lifecycle commit with collections config instead")
} Prevention
- Pass collection configuration via the _lifecycle commit flow, not legacy instantiate
- Avoid chaincodes that write private data during legacy instantiate
- Audit deploy scripts for lscc + collections combinations
When it happens
Trigger: Calling lscc instantiate/upgrade with a chaincode that defines collections, causing the simulation to write private data (collection config updates) which lscc proposals may not carry.
Common situations: Deploying a chaincode with collection-config via the legacy lscc path; old deployment scripts combining private collections with instantiate; missing the separate collection-config handling introduced later.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- no collection config for chaincode %#v
- failed to parse collection config
- tx creator does not have read access permission on privateda
- tx creator does not have write access permission on privated
- private data APIs are not allowed in chaincode Init()
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/ee96a87f69f96442.
Report an issue: GitHub.