hyperledger/fabric · error
failed connecting to
Error message
failed connecting to %s: %v
What it means
The discovery client stub wraps the low-level gRPC failure of discovery.Service.Send into a single contextual error. The underlying %v contains the real cause (TLS handshake failure, connection refused, authentication rejection, deadline exceeded). It surfaces whenever the signed discovery request could not be delivered or processed by the peer.
Solutions
- Verify the peer address/port and that discovery service is enabled (CORE_PEER_DISCOVERY_ENABLED... / peer.discovery.enabled=true in network config)
- Check TLS: ensure tlsCertHash matches and CA certs are trusted by the client context
- Re-enroll or refresh the client identity if the peer rejected the signature/auth info
- Increase the timeout and confirm network connectivity (nc/curl to the peer port)
Example fix
// before
resp, err := disc.Send(0, req, authInfo) // zero timeout fails fast
// after
resp, err := disc.Send(5*time.Second, req, &discovery.AuthInfo{
ClientIdentity: signer.Creator,
ClientTlsCertHash: comm.TLSCertHash,
})
if err != nil {
return fmt.Errorf("failed connecting to %s: %w", server, err)
} Defensive patterns
Strategy: retry
Validate before calling
// pre-check connectivity before Send
conn, err := grpc.Dial(server, grpc.WithTransportCredentials(creds))
if err != nil {
return fmt.Errorf("peer %s unreachable before discovery: %w", server, err)
}
conn.Close() Try / catch
resp, err := stub.Send(timeout, req, authInfo)
if err != nil {
var wrapped string = err.Error()
if strings.Contains(wrapped, "deadline exceeded") {
// retry with backoff
} else if strings.Contains(wrapped, "certificate") || strings.Contains(wrapped, "tls") {
// fix TLS config, do not retry
}
return fmt.Errorf("discovery to %s failed: %w", server, err)
} Prevention
- Use a non-zero timeout (e.g. 5s) and retry with backoff
- Keep ClientTlsCertHash in sync with the peer's TLS cert
- Verify discovery service is enabled on the target peer
- Rotate enrollment certs before expiry
- Test peer reachability with grpc health checks in CI
When it happens
Trigger: Peer unreachable or wrong port; TLS certificate hash mismatch (ClientTlsCertHash does not match peer TLS config); peer's discovery service rejects the auth info (stale enrollment cert); timeout elapsing before response.
Common situations: Discovery service not enabled on the target peer; connecting through a proxy that strips TLS; expired or rotated MSP certificates in the local context; firewall blocking the peer port in Docker/Kubernetes environments.
Related errors
- client claimed TLS hash doesn't match computed TLS hash…
- client didn't send a TLS certificate
- Error getting broadcast client
- failed connecting to discovery service
- access denied
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/5944d43826baae46.
Report an issue: GitHub.
Appendix: source
Thrown at discovery/cmd/stub.go:82
comm, err := comm.NewClient(conf.TLSConfig)
if err != nil {
return nil, err
}
signer, err := signer.NewSigner(conf.SignerConfig)
if err != nil {
return nil, err
}
timeout, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
disc := discoveryclient.NewClient(comm.NewDialer(server), signer.Sign, 0)
resp, err := disc.Send(timeout, req, &discovery.AuthInfo{
ClientIdentity: signer.Creator,
ClientTlsCertHash: comm.TLSCertHash,
})
if err != nil {
return nil, errors.Errorf("failed connecting to %s: %v", server, err)
}
return &response{
Response: resp,
}, nil
}
// RawStub is a stub that communicates with the discovery service
// without any intermediary.
type RawStub struct{}
// Send sends the request, and receives a response
func (stub *RawStub) Send(server string, conf common.Config, req *discoveryclient.Request) (ServiceResponse, error) {
comm, err := comm.NewClient(conf.TLSConfig)
if err != nil {
return nil, err
}
signer, err := signer.NewSigner(conf.SignerConfig)
if err != nil {View on GitHub (pinned to 2736b63f8f)