{"record":{"id":"625274062b474ad9","repo":"hyperledger/fabric","slug":"expected-key-s-found-s","errorCode":null,"errorMessage":"expected key %s, found %s","messagePattern":"expected key (.+?), found (.+?)","errorType":"validation","errorClass":"VSCCEndorsementPolicyError","httpStatus":null,"severity":"error","filePath":"core/handlers/validation/builtin/v12/validation_logic.go","lineNumber":607,"sourceCode":"\t\tcdLedger, ccExistsOnLedger, err := vscc.getInstantiatedCC(chid, cdsArgs.ChaincodeSpec.ChaincodeId.Name)\n\t\tif err != nil {\n\t\t\treturn &commonerrors.VSCCExecutionFailureError{Err: err}\n\t\t}\n\n\t\t/******************************************/\n\t\t/* security check 0 - validation of rwset */\n\t\t/******************************************/\n\t\t// there has to be a write-set\n\t\tif lsccrwset == nil {\n\t\t\treturn policyErr(fmt.Errorf(\"No read write set for lscc was found\"))\n\t\t}\n\t\t// there must be at least one write\n\t\tif len(lsccrwset.Writes) < 1 {\n\t\t\treturn policyErr(fmt.Errorf(\"LSCC must issue at least one single putState upon deploy/upgrade\"))\n\t\t}\n\t\t// the first key name must be the chaincode id provided in the deployment spec\n\t\tif lsccrwset.Writes[0].Key != cdsArgs.ChaincodeSpec.ChaincodeId.Name {\n\t\t\treturn policyErr(fmt.Errorf(\"expected key %s, found %s\", cdsArgs.ChaincodeSpec.ChaincodeId.Name, lsccrwset.Writes[0].Key))\n\t\t}\n\t\t// the value must be a ChaincodeData struct\n\t\tcdRWSet := &ccprovider.ChaincodeData{}\n\t\terr = proto.Unmarshal(lsccrwset.Writes[0].Value, cdRWSet)\n\t\tif err != nil {\n\t\t\treturn policyErr(fmt.Errorf(\"unmarshalling of ChaincodeData failed, error %s\", err))\n\t\t}\n\t\t// the chaincode name in the lsccwriteset must match the chaincode name in the deployment spec\n\t\tif cdRWSet.Name != cdsArgs.ChaincodeSpec.ChaincodeId.Name {\n\t\t\treturn policyErr(fmt.Errorf(\"expected cc name %s, found %s\", cdsArgs.ChaincodeSpec.ChaincodeId.Name, cdRWSet.Name))\n\t\t}\n\t\t// the chaincode version in the lsccwriteset must match the chaincode version in the deployment spec\n\t\tif cdRWSet.Version != cdsArgs.ChaincodeSpec.ChaincodeId.Version {\n\t\t\treturn policyErr(fmt.Errorf(\"expected cc version %s, found %s\", cdsArgs.ChaincodeSpec.ChaincodeId.Version, cdRWSet.Version))\n\t\t}\n\t\t// it must only write to 2 namespaces: LSCC's and the cc that we are deploying/upgrading\n\t\tfor _, ns := range txRWSet.NsRwSets {\n\t\t\tif ns.NameSpace != \"lscc\" && ns.NameSpace != cdRWSet.Name && len(ns.KvRwSet.Writes) > 0 {","sourceCodeStart":589,"sourceCodeEnd":625,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/handlers/validation/builtin/v12/validation_logic.go#L589-L625","documentation":"The first key lscc writes must exactly equal the chaincode name declared in the deployment spec (ChaincodeSpec.ChaincodeId.Name). A mismatch means the rwset registers a different chaincode than the one the transaction claims to deploy, so validation fails as a policy error.","triggerScenarios":"Transaction where lsccrwset.Writes[0].Key differs from cdsArgs.ChaincodeSpec.ChaincodeId.Name — e.g. spec tampered after endorsement, or rwset assembled out of order or from a different deploy invocation.","commonSituations":"Manually constructed or replayed envelopes; SDK bugs mixing chaincode names; upgrading chaincode A with a spec naming chaincode B; endorsement payload edited in transit.","solutions":["Resubmit the deploy/upgrade ensuring the ChaincodeSpec chaincode name matches the name passed to lscc.","Do not modify the proposal payload after endorsement (invalidates signature and consistency).","Use a current SDK to build the instantiate/upgrade request with a single consistent chaincodeId.","Verify the first lscc write key matches the intended chaincode before submission."],"exampleFix":"// before\nrequest.chaincodeId = 'mycc'\nrequest.args = deployArgsFor('othercc') // mismatch\n// after\nrequest.chaincodeId = 'mycc'\nrequest.args = deployArgsFor('mycc')","handlingStrategy":"validation","validationCode":"if ns.KvRwSet.Writes[0].Key != chaincodeSpec.ChaincodeId.Name {\n    return fmt.Errorf(\"lscc first write key %q does not match spec name %q\", ns.KvRwSet.Writes[0].Key, chaincodeSpec.ChaincodeId.Name)\n}","typeGuard":"func firstWriteKeyMatches(ns *rwset.NsRwSet, name string) bool {\n    return ns != nil && len(ns.KvRwSet.Writes) > 0 && ns.KvRwSet.Writes[0].Key == name\n}","tryCatchPattern":"if err := submitTx(envelope); err != nil {\n    if strings.Contains(err.Error(), \"expected key \") {\n        // rebuild proposal with a consistent chaincodeId; do not edit endorsed payloads\n    }\n}","preventionTips":["Never modify proposal payloads after endorsement","Use one chaincodeId consistently in the SDK request","Avoid replaying envelopes across different deploy attempts"],"tags":["hyperledger-fabric","lscc","chaincode-name","transaction-validation"],"backgroundTag":"chaincode-deploy-mismatch","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"}