hyperledger/fabric · error
error receiving from peer deliver service
Error message
error receiving from peer deliver service
What it means
peerDeliverService.Recv waits on the peer's deliver gRPC stream; the underlying Recv failed, so the error is wrapped with "error receiving from peer deliver service". No response was received because the stream to the peer broke or was closed.
Source
Thrown at internal/peer/common/deliverclient.go:226
// check for client certificate and create hash if present
if len(pc.Certificate().Certificate) > 0 {
tlsCertHash = util.ComputeSHA256(pc.Certificate().Certificate[0])
}
ds := &peerDeliverService{d}
p := &DeliverClient{
Signer: signer,
Service: ds,
ChannelID: channelID,
TLSCertHash: tlsCertHash,
BestEffort: bestEffort,
}
return p, nil
}
func (p *peerDeliverService) Recv() (*ab.DeliverResponse, error) {
pbResp, err := p.Deliver_DeliverClient.Recv()
if err != nil {
return nil, errors.Wrap(err, "error receiving from peer deliver service")
}
abResp := &ab.DeliverResponse{}
switch t := pbResp.Type.(type) {
case *pb.DeliverResponse_Status:
abResp.Type = &ab.DeliverResponse_Status{Status: t.Status}
case *pb.DeliverResponse_Block:
abResp.Type = &ab.DeliverResponse_Block{Block: t.Block}
default:
return nil, errors.Errorf("response error: unknown type %T", t)
}
return abResp, nil
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Reconnect/re-establish the deliver stream and retry Recv
- Check peer logs and health at the time of the failure
- Configure gRPC keepalives to keep long-lived streams alive through proxies
- Validate TLS credentials and endpoint configuration
Example fix
// before
resp, err := pds.Recv()
if err != nil { return nil, err }
// after
resp, err := pds.Recv()
if err != nil {
pds.reconnect()
resp, err = pds.Recv()
} Defensive patterns
Strategy: retry
Validate before calling
// health-check the peer before subscribing
c, err := grpc.DialContext(ctx, peerAddr, grpc.WithTransportCredentials(creds), grpc.WithBlock())
if err != nil { return fmt.Errorf("peer unavailable: %w", err) } Try / catch
resp, err := pds.Recv()
if err != nil {
if isStreamBroken(err) { // io.EOF, codes.Unavailable, codes.Canceled
pds.reconnect(ctx)
resp, err = pds.Recv()
}
} Prevention
- Register stream-error handlers that reconnect automatically
- Configure gRPC keepalive pings for long-lived peer streams
- Monitor peer restarts and re-subscribe on failure
When it happens
Trigger: p.Deliver_DeliverClient.Recv() errors — network drop, TLS failure, peer shutdown, deadline exceeded, or the peer cancelled the deliver stream.
Common situations: Peer restart or crash during event/deliver listening, network flaps, keepalive/idle timeouts closing long-lived streams, TLS certificate rotation.
Related errors
- error receiving
- message is nil
- context finished before block retrieved
- orderer `%s` hung up without sending status
- cannot find ledger for channel %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/2704b2af63e37695.
Report an issue: GitHub.