hyperledger/fabric · info

not found

Error message

not found

What it means

ErrNotFound in discovery/client/api.go:18 is a sentinel error (errors.New("not found")) meaning an element wasn't found. The discovery client's Get, Config, parsePeers, and Endorsers return it when a requested element does not exist in the response. It is distinct from LevelDB's leveldb.ErrNotFound, which the ledger helper translates into a nil value, not an application error.

Source

Thrown at discovery/client/api.go:18

/*
Copyright IBM Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package discovery

import (
	"github.com/hyperledger/fabric-protos-go-apiv2/discovery"
	"github.com/hyperledger/fabric-protos-go-apiv2/peer"
	"github.com/hyperledger/fabric/gossip/protoext"
	"github.com/pkg/errors"
	"google.golang.org/grpc"
)

// ErrNotFound defines an error that means that an element wasn't found
var ErrNotFound = errors.New("not found")

// Signer signs a message and returns the signature and nil,
// or nil and error on failure
type Signer func(msg []byte) ([]byte, error)

// Dialer connects to the server
type Dialer func() (*grpc.ClientConn, error)

// Response aggregates several responses from the discovery service
type Response interface {
	// ForChannel returns a ChannelResponse in the context of a given channel
	ForChannel(string) ChannelResponse

	// ForLocal returns a LocalResponse in the context of no channel
	ForLocal() LocalResponse
}

// ChannelResponse aggregates responses for a given channel

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check errors.Is(err, discovery.ErrNotFound) to detect this sentinel and handle it as 'no data', not a hard failure
  2. Verify the channel name and chaincode name are correct and that the peer has joined the channel
  3. Ensure the peer has the discovery service enabled and the chaincode installed/committed on at least one peer
  4. Retry after peers finish gossip membership sync if the network just started

Example fix

// before: treating any error as fatal
resp, err := client.Send(ctx, req, auth)
if err != nil { return err }

// after: handle not-found distinctly
if errors.Is(err, discovery.ErrNotFound) {
    return nil, nil // element genuinely absent
}
Defensive patterns

Strategy: type-guard

Validate before calling

if err != nil && errors.Is(err, discovery.ErrNotFound) {
    // element absent: channel not joined, chaincode not installed, etc.
}

Type guard

func isNotFound(err error) bool { return errors.Is(err, discovery.ErrNotFound) }

Try / catch

peers, err := client.Send(ctx, req, auth)
if isNotFound(err) {
    return nil, nil // handle absence gracefully
}
if err != nil {
    return nil, err
}

Prevention

When it happens

Trigger: Calling client.Get/Config/Endorsers when the discovery response contains no matching element (e.g. no peers satisfy the request, channel not found, peer has no ledger for the channel), hitting the `return nil, ErrNotFound` branch in discovery/client/client.go:215.

Common situations: Querying a channel the peer isn't joined to; discovery service has no membership data yet; asking for endorsers of a chaincode not installed on any peer; typo'd chaincode name.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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