{"record":{"id":"7777570866d41c76","repo":"hyperledger/fabric","slug":"chaincode-definition-for-s-at-sequence-d-on-ch","errorCode":null,"errorMessage":"chaincode definition for '%s' at sequence %d on channel '%s' has not yet been approved by this org","messagePattern":"chaincode definition for '(.+?)' at sequence (.+?) on channel '(.+?)' has not yet been approved by this org","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/lifecycle/endorsement_info.go","lineNumber":89,"sourceCode":"\tif currentSequence == 0 {\n\t\treturn nil, false, nil\n\t}\n\n\tchaincodeInfo, err := cei.Cache.ChaincodeInfo(channelID, chaincodeName)\n\tif err != nil {\n\t\treturn nil, false, errors.WithMessage(err, \"could not get approved chaincode info from cache\")\n\t}\n\n\tif chaincodeInfo.Definition.Sequence != currentSequence {\n\t\t// TODO this is a transient error which indicates that this query executor is executing against a chaincode\n\t\t// whose definition has already changed (the cache may be ahead of the committed state, but never behind).  In this\n\t\t// case, we should simply abort the tx, and re-acquire a query executor and re-execute.  There is no reason this\n\t\t// error needs to be returned to the client.\n\t\treturn nil, false, errors.Errorf(\"chaincode cache at sequence %d but current sequence is %d, chaincode definition for '%s' changed during invoke\", chaincodeInfo.Definition.Sequence, currentSequence, chaincodeName)\n\t}\n\n\tif !chaincodeInfo.Approved {\n\t\treturn nil, false, errors.Errorf(\"chaincode definition for '%s' at sequence %d on channel '%s' has not yet been approved by this org\", chaincodeName, currentSequence, channelID)\n\t}\n\n\tif chaincodeInfo.InstallInfo == nil {\n\t\tif cei.UserRunsCC {\n\t\t\tchaincodeInfo.InstallInfo = &ChaincodeInstallInfo{\n\t\t\t\tPackageID: chaincodeName + \":\" + chaincodeInfo.Definition.EndorsementInfo.Version,\n\t\t\t}\n\t\t\treturn chaincodeInfo, true, nil\n\t\t}\n\t\treturn nil, false, errors.Errorf(\"chaincode definition for '%s' exists, but chaincode is not installed\", chaincodeName)\n\t}\n\n\treturn chaincodeInfo, true, nil\n}\n\n// ChaincodeEndorsementInfo returns the information necessary to handle a chaincode invocation request, as well as a function to\n// enforce security checks on the chaincode (in case the definition is from the legacy lscc).\nfunc (cei *ChaincodeEndorsementInfoSource) ChaincodeEndorsementInfo(channelID, chaincodeName string, qe ledger.SimpleQueryExecutor) (*ChaincodeEndorsementInfo, error) {","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/lifecycle/endorsement_info.go#L71-L107","documentation":"CachedChaincodeInfo returns this when the chaincode definition exists at the current committed sequence but chaincodeInfo.Approved is false — i.e., this organization has not approved the chaincode definition for that name/sequence on the channel. Without a local approval, the peer refuses to supply endorsement info for V2.0 lifecycle chaincode.","triggerScenarios":"ChaincodeEndorsementInfo -> CachedChaincodeInfo finds a committed definition at currentSequence whose Approved flag is false because approveformyorg was never run (or was run for a different sequence/packageID) on this peer's org.","commonSituations":"One org committed a definition while another org skipped approval; approval done before sequence changed so it no longer matches; packageID in approval doesn't match the installed package; new peer joined org without running lifecycle approve.","solutions":["Run `peer lifecycle chaincode approveformyorg` on the org with the same definition (name, version, sequence, packageID) that was committed.","Check with `peer lifecycle chaincode checkcommitreadiness` which orgs are still missing approvals.","Verify the installed packageID matches the one referenced in the approval (peer lifecycle chaincode queryinstalled).","If the sequence advanced, re-approve for the new sequence."],"exampleFix":"// before: only one org approved, then commit\npeer lifecycle chaincode commit -o orderer:7050 --channelID ch1 --name cc -v 1.0 --sequence 1\n// after: every org approves first\npeer lifecycle chaincode approveformyorg -o orderer:7050 --channelID ch1 --name cc --version 1.0 --package-id cc_abc:abc --sequence 1\npeer lifecycle chaincode commit ...","handlingStrategy":"validation","validationCode":"// shell: check readiness across orgs before commit/endorse\npeer lifecycle chaincode checkcommitreadiness \\\n  --channelID ch1 --name mycc --version 1.0 --sequence 1 --output json\n# expect every org's approved flag to be true","typeGuard":null,"tryCatchPattern":"err := endorse(...)\nif err != nil && strings.Contains(err.Error(), \"has not yet been approved by this org\") {\n  // run approveformyorg for this org then retry\n}","preventionTips":["Run approveformyorg on every org before commit.","Verify approvals with checkcommitreadiness.","Re-approve whenever sequence or packageID changes.","For new peers, ensure the org's approval exists (approval is org-level, stored on each peer's ledger)."],"tags":["hyperledger-fabric","chaincode-lifecycle","approval","v20-lifecycle"],"backgroundTag":"chaincode-definition-not-approved","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}