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 channelView on GitHub (pinned to 2736b63f8f)
Solutions
- Check errors.Is(err, discovery.ErrNotFound) to detect this sentinel and handle it as 'no data', not a hard failure
- Verify the channel name and chaincode name are correct and that the peer has joined the channel
- Ensure the peer has the discovery service enabled and the chaincode installed/committed on at least one peer
- 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
- Confirm the peer has joined the channel and installed the chaincode before querying discovery
- Use errors.Is with the sentinel instead of string comparison
- Wait for gossip membership convergence on fresh networks
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
- organization %s not found
- no such block number [%d] in index
- ledger already opened
- ledger mgmt should be initialized before using
- chaincode %s not found
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/922f36ef896071ae.
Report an issue: GitHub.