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

  1. Reconnect/re-establish the deliver stream and retry Recv
  2. Check peer logs and health at the time of the failure
  3. Configure gRPC keepalives to keep long-lived streams alive through proxies
  4. 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

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


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