{"record":{"id":"c683af7ce85fb234","repo":"hyperledger/fabric","slug":"expected-d-endorsement-descriptors-but-got-only","errorCode":null,"errorMessage":"expected %d endorsement descriptors but got only %d","messagePattern":"expected (.+?) endorsement descriptors but got only (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/client/client.go","lineNumber":477,"sourceCode":"\t\tif err != nil {\n\t\t\tkey := key{\n\t\t\t\tqueryType: protoext.ChaincodeQueryType,\n\t\t\t\tk:         ch,\n\t\t\t}\n\t\t\tresp[key] = errors.New(err.Content)\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := resp.mapEndorsersOfChannel(ccQueryRes, ch, chaincodeQueryMapping[index]); err != nil {\n\t\t\treturn errors.Wrapf(err, \"failed assembling endorsers of channel %s\", ch)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (resp response) mapEndorsersOfChannel(ccRs *discovery.ChaincodeQueryResult, channel string, invocationChain []InvocationChain) error {\n\tif len(ccRs.Content) < len(invocationChain) {\n\t\treturn errors.Errorf(\"expected %d endorsement descriptors but got only %d\", len(invocationChain), len(ccRs.Content))\n\t}\n\tfor i, desc := range ccRs.Content {\n\t\texpectedCCName := invocationChain[i][0].Name\n\t\tif desc.Chaincode != expectedCCName {\n\t\t\treturn errors.Errorf(\"expected chaincode %s but got endorsement descriptor for %s\", expectedCCName, desc.Chaincode)\n\t\t}\n\t\tkey := key{\n\t\t\tqueryType:       protoext.ChaincodeQueryType,\n\t\t\tk:               channel,\n\t\t\tinvocationChain: invocationChain[i].String(),\n\t\t}\n\n\t\tdescriptor, err := resp.createEndorsementDescriptor(desc, channel)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tresp[key] = descriptor\n\t}","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/client/client.go#L459-L495","documentation":"mapEndorsersOfChannel expects the discovery server's ChaincodeQueryResult to contain at least one endorsement descriptor per InvocationChain the client requested. If the server returned fewer descriptors (len(ccRs.Content) < len(invocationChain)), this error reports the expected and actual counts. It indicates a client/server mismatch: the caller asked for more chaincode endorsements than the server's result carries.","triggerScenarios":"Sending a chaincode query with an InvocationChain of N entries (e.g. chaincode-to-chaincode calls or collection-based endorsement) while the discovery server returns fewer than N descriptors in ChaincodeQueryResult.Content.","commonSituations":"Fabric v1 client querying a v2-discovery peer where chaincode interest semantics changed; requesting endorsement for a chaincode that isn't installed anywhere in the channel so the server drops its descriptor; stale discovery data after chaincode upgrade.","solutions":["Verify every chaincode in the InvocationChain is installed on at least one peer in the channel","Check the discovery client and peer Fabric versions match (v1 vs v2 discovery behavior)","Re-run the discovery query after chaincode install/commit completes","Reduce or correct the chaincode interest so it reflects what is actually deployed","Enable discovery server debug logs to see why descriptors were omitted"],"exampleFix":"// before: requesting a chaincode that isn't installed\nchaincode := InvocationChain{{Name: \"mycc\"}}\n// after: verify deployment first, or align interest with installed chaincodes\nif !isChaincodeInstalled(peer, \"mycc\") {\n\treturn fmt.Errorf(\"mycc is not installed on any peer of the channel\")\n}\nchaincode := InvocationChain{{Name: \"mycc\"}}","handlingStrategy":"validation","validationCode":"// Verify every chaincode in the interest is installed before discovery\nfor _, chain := range invocationChains {\n\tfor _, cc := range chain {\n\t\tif !isChaincodeInstalledOnChannel(channel, cc.Name) {\n\t\t\treturn fmt.Errorf(\"chaincode %s not installed on channel %s\", cc.Name, channel)\n\t\t}\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n\tif strings.Contains(err.Error(), \"endorsement descriptors but got only\") {\n\t\t// fallback: re-query or reduce chaincode interest\n\t\treturn retryDiscoveryQuery(ctx)\n\t}\n\treturn err\n}","preventionTips":["Install all chaincodes in the invocation chain before discovery","Match client interest semantics to the peer's Fabric version","Re-run discovery after lifecycle (install/commit) operations complete","Keep chaincode interest lists minimal and accurate"],"tags":["hyperledger-fabric","discovery-service","endorsement-descriptor","chaincode"],"backgroundTag":"endorsement-descriptor-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"}