hyperledger/fabric · error

expected chaincode %s but got endorsement descriptor for %s

Error message

expected chaincode %s but got endorsement descriptor for %s

What it means

mapEndorsersOfChannel matches each returned endorsement descriptor positionally with the requested InvocationChain: invocationChain[i][0].Name must equal desc.Chaincode. If the server returned a descriptor for a different chaincode than expected at index i, this error reports both names. It signals the client's requested chaincode order and the server's descriptor order disagree, usually because the wrong chaincode name was requested or discovery data is stale.

Source

Thrown at discovery/client/client.go:482

			resp[key] = errors.New(err.Content)
			continue
		}

		if err := resp.mapEndorsersOfChannel(ccQueryRes, ch, chaincodeQueryMapping[index]); err != nil {
			return errors.Wrapf(err, "failed assembling endorsers of channel %s", ch)
		}
	}
	return nil
}

func (resp response) mapEndorsersOfChannel(ccRs *discovery.ChaincodeQueryResult, channel string, invocationChain []InvocationChain) error {
	if len(ccRs.Content) < len(invocationChain) {
		return errors.Errorf("expected %d endorsement descriptors but got only %d", len(invocationChain), len(ccRs.Content))
	}
	for i, desc := range ccRs.Content {
		expectedCCName := invocationChain[i][0].Name
		if desc.Chaincode != expectedCCName {
			return errors.Errorf("expected chaincode %s but got endorsement descriptor for %s", expectedCCName, desc.Chaincode)
		}
		key := key{
			queryType:       protoext.ChaincodeQueryType,
			k:               channel,
			invocationChain: invocationChain[i].String(),
		}

		descriptor, err := resp.createEndorsementDescriptor(desc, channel)
		if err != nil {
			return err
		}
		resp[key] = descriptor
	}

	return nil
}

func (resp response) createEndorsementDescriptor(desc *discovery.EndorsementDescriptor, channel string) (*endorsementDescriptor, error) {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Compare the two chaincode names in the error — fix the name passed in the InvocationChain/chaincode interest
  2. Ensure the chaincode interest matches exactly what is installed and committed on the channel
  3. Make sure you query the intended channel (channel name typo)
  4. Re-run discovery after chaincode lifecycle operations finish (install/commit)
  5. Clear any cached invocation chain / chaincode interest built from a previous channel or version

Example fix

// before
chaincode := InvocationChain{{Name: "myCC"}} // typo
// after
chaincode := InvocationChain{{Name: "mycc"}} // matches installed chaincode name
Defensive patterns

Strategy: validation

Validate before calling

// Validate chaincode names against committed definitions
for _, chain := range invocationChains {
	if !isChaincodeCommitted(channel, chain[0].Name) {
		return fmt.Errorf("chaincode %q not committed on %s", chain[0].Name, channel)
	}
}

Try / catch

if err != nil && strings.Contains(err.Error(), "but got endorsement descriptor for") {
	log.Printf("chaincode name mismatch: %v — check requested name vs installed name", err)
	return err
}

Prevention

When it happens

Trigger: A chaincode query where the descriptor at position i is for a chaincode other than invocationChain[i][0].Name — e.g. typos in the chaincode name, querying a different channel that has a chaincode with the same position but different name, or server response ordering differing from the request.

Common situations: Misspelled chaincode name in ForChannel call; referencing the default vs upgraded chaincode name; a channel where a different chaincode occupies the slot because the requested one isn't installed; client code caching invocation chains from another channel.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/bbeba8aedaf6aaeb. Report an issue: GitHub.