{"record":{"id":"2704b2af63e37695","repo":"hyperledger/fabric","slug":"error-receiving-from-peer-deliver-service","errorCode":null,"errorMessage":"error receiving from peer deliver service","messagePattern":"error receiving from peer deliver service","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/common/deliverclient.go","lineNumber":226,"sourceCode":"\t// check for client certificate and create hash if present\n\tif len(pc.Certificate().Certificate) > 0 {\n\t\ttlsCertHash = util.ComputeSHA256(pc.Certificate().Certificate[0])\n\t}\n\tds := &peerDeliverService{d}\n\tp := &DeliverClient{\n\t\tSigner:      signer,\n\t\tService:     ds,\n\t\tChannelID:   channelID,\n\t\tTLSCertHash: tlsCertHash,\n\t\tBestEffort:  bestEffort,\n\t}\n\treturn p, nil\n}\n\nfunc (p *peerDeliverService) Recv() (*ab.DeliverResponse, error) {\n\tpbResp, err := p.Deliver_DeliverClient.Recv()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"error receiving from peer deliver service\")\n\t}\n\n\tabResp := &ab.DeliverResponse{}\n\n\tswitch t := pbResp.Type.(type) {\n\tcase *pb.DeliverResponse_Status:\n\t\tabResp.Type = &ab.DeliverResponse_Status{Status: t.Status}\n\tcase *pb.DeliverResponse_Block:\n\t\tabResp.Type = &ab.DeliverResponse_Block{Block: t.Block}\n\tdefault:\n\t\treturn nil, errors.Errorf(\"response error: unknown type %T\", t)\n\t}\n\n\treturn abResp, nil\n}\n","sourceCodeStart":208,"sourceCodeEnd":242,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/common/deliverclient.go#L208-L242","documentation":"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.","triggerScenarios":"p.Deliver_DeliverClient.Recv() errors — network drop, TLS failure, peer shutdown, deadline exceeded, or the peer cancelled the deliver stream.","commonSituations":"Peer restart or crash during event/deliver listening, network flaps, keepalive/idle timeouts closing long-lived streams, TLS certificate rotation.","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"],"exampleFix":"// before\nresp, err := pds.Recv()\nif err != nil { return nil, err }\n// after\nresp, err := pds.Recv()\nif err != nil {\n    pds.reconnect()\n    resp, err = pds.Recv()\n}","handlingStrategy":"retry","validationCode":"// health-check the peer before subscribing\nc, err := grpc.DialContext(ctx, peerAddr, grpc.WithTransportCredentials(creds), grpc.WithBlock())\nif err != nil { return fmt.Errorf(\"peer unavailable: %w\", err) }","typeGuard":null,"tryCatchPattern":"resp, err := pds.Recv()\nif err != nil {\n    if isStreamBroken(err) { // io.EOF, codes.Unavailable, codes.Canceled\n        pds.reconnect(ctx)\n        resp, err = pds.Recv()\n    }\n}","preventionTips":["Register stream-error handlers that reconnect automatically","Configure gRPC keepalive pings for long-lived peer streams","Monitor peer restarts and re-subscribe on failure"],"tags":["fabric","grpc","deliver","peer","stream-error"],"backgroundTag":"grpc-stream-receive-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}