hyperledger/fabric · error

chaincode interest is nil

Error message

chaincode interest is nil

What it means

validateCCQuery iterates the ChaincodeQuery's Interests and rejects any entry that is a nil pointer. A nil interest carries no chaincode information, so the server fails fast with this error rather than dereferencing nil.

Source

Thrown at discovery/service.go:268

	computedHash := certHashFromContext(ctx)
	if len(computedHash) == 0 {
		return nil, errors.New("client didn't send a TLS certificate")
	}
	if !bytes.Equal(computedHash, req.Authentication.ClientTlsCertHash) {
		claimed := hex.EncodeToString(req.Authentication.ClientTlsCertHash)
		logger.Warningf("client claimed TLS hash %s doesn't match computed TLS hash from gRPC stream %s", claimed, hex.EncodeToString(computedHash))
		return nil, errors.New("client claimed TLS hash doesn't match computed TLS hash from gRPC stream")
	}
	return req, nil
}

func validateCCQuery(ccQuery *discovery.ChaincodeQuery) error {
	if len(ccQuery.Interests) == 0 {
		return errors.New("chaincode query must have at least one chaincode interest")
	}
	for _, interest := range ccQuery.Interests {
		if interest == nil {
			return errors.New("chaincode interest is nil")
		}
		if len(interest.Chaincodes) == 0 {
			return errors.New("chaincode interest must contain at least one chaincode")
		}
		for _, cc := range interest.Chaincodes {
			if cc.Name == "" {
				return errors.New("chaincode name in interest cannot be empty")
			}
		}
	}
	return nil
}

func wrapError(err error) *discovery.QueryResult {
	return &discovery.QueryResult{
		Result: &discovery.QueryResult_Error{
			Error: &discovery.Error{
				Content: err.Error(),

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure every element of Interests is a non-nil ChaincodeInterest; filter out nils before sending
  2. Avoid pre-allocating with make(..., n) and leaving entries unset; build with append
  3. Add a client-side loop checking each interest for nil before invoking discovery

Example fix

// before
interests := make([]discovery.ChaincodeInterest, len(names)) // trailing entries nil
// after
var interests []discovery.ChaincodeInterest
for _, n := range names {
    interests = append(interests, discovery.ChaincodeInterest{Chaincodes: []discovery.ChaincodeCall{{Name: n}}})
}
Defensive patterns

Strategy: validation

Validate before calling

func dropNilInterests(q *discovery.ChaincodeQuery) error {
    for i, in := range q.Interests {
        if in == nil {
            return fmt.Errorf("interest at index %d is nil", i)
        }
    }
    return nil
}

Type guard

func allInterestsNonNil(q *discovery.ChaincodeQuery) bool {
    for _, in := range q.Interests {
        if in == nil {
            return false
        }
    }
    return true
}

Try / catch

if err := dropNilInterests(query); err != nil {
    return fmt.Errorf("sanitize interests before sending: %w", err)
}
resp, err := client.Send(ctx, req)
if err != nil {
    if strings.Contains(err.Error(), "chaincode interest is nil") {
        return fmt.Errorf("interests slice contains nil entries; rebuild with append: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling the chaincode discovery query (via chaincodeQuery) with Interests containing a nil *discovery.ChaincodeInterest element, e.g. a slice built with make([]discovery.ChaincodeInterest, n) and partially filled, or appending a nil pointer.

Common situations: Pre-allocating an interests slice of fixed size and only populating some entries; a JSON/config deserialization that produced null entries; an append that mistakenly added an uninitialized pointer.

Related errors


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