{"record":{"id":"7efcfc280bfc0e91","repo":"hyperledger/fabric","slug":"recv-error-v-closing-connection","errorCode":null,"errorMessage":"Recv() error: %v, closing connection","messagePattern":"Recv\\(\\) error: (.+?), closing connection","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/accesscontrol/interceptor.go","lineNumber":49,"sourceCode":"\nfunc newInterceptor(srv pb.ChaincodeSupportServer, auth authorization) pb.ChaincodeSupportServer {\n\treturn &interceptor{\n\t\tnext: srv,\n\t\tauth: auth,\n\t}\n}\n\n// Register makes the interceptor implement ChaincodeSupportServer\nfunc (i *interceptor) Register(stream pb.ChaincodeSupport_RegisterServer) error {\n\tis := &interceptedStream{\n\t\tincMessages:  make(chan *pb.ChaincodeMessage, 1),\n\t\tstream:       stream,\n\t\tServerStream: stream,\n\t\tauth:         i.auth,\n\t}\n\tmsg, err := stream.Recv()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Recv() error: %v, closing connection\", err)\n\t}\n\terr = is.auth(msg, is.ServerStream)\n\tif err != nil {\n\t\treturn err\n\t}\n\tis.incMessages <- msg\n\tclose(is.incMessages)\n\treturn i.next.Register(is)\n}\n\ntype interceptedStream struct {\n\tincMessages chan *pb.ChaincodeMessage\n\tstream      ChaincodeStream\n\tgrpc.ServerStream\n\tauth authorization\n}\n\n// Send sends a chaincode message","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/accesscontrol/interceptor.go#L31-L67","documentation":"This error is returned by the access-control interceptor's Register method in Hyperledger Fabric's chaincode support gRPC server. When a chaincode container connects and the server calls stream.Recv() to pick up the very first chaincode message (usually the REGISTER message), a transport-level or stream-level failure occurred before any authentication could happen. The connection is closed immediately because the handshake never completed, so the peer cannot identify or authorize this chaincode connection.","triggerScenarios":"A chaincode dials the peer's ChaincodeSupport gRPC service (ccstream / chaincode-support port) and the very first Recv() fails: the chaincode process died or crashed immediately after connecting, the gRPC stream was cancelled or timed out mid-handshake, TLS handshake/certificate mismatch killed the stream, or the client sent nothing and disconnected.","commonSituations":"Chaincode container crashes on startup (OOM, bad user chaincode binary); peer TLS root certificates regenerated while chaincode images still carry old certs; network drops between kube/docker network and peer; chaincode connecting to wrong peer address or wrong port; resource-starved clusters evicting the chaincode pod mid-registration.","solutions":["Inspect the chaincode container logs for a crash or exit right after start and fix the root cause (missing binary, OOM, bad build).","Verify peer.chaincode.address and peer TLS config on the peer match what the chaincode connects to; regenerate/redeploy chaincode images after any peer TLS cert rotation.","Check network connectivity between the chaincode container and the peer's chaincode-listen port (firewalls, docker network, k8s service).","Retry launching the chaincode (restart the chaincode container or redeploy the chaincode) once the environment is stable."],"exampleFix":"// before: peer TLS certs rotated but chaincode image still has old root certs; connection dies before REGISTER\n// after: rebuild chaincode image with current peer root certs\n# rebuild the chaincode image so its CA certs match the peer's current TLS CA\ndocker build -t myorg/mycc:latest . && kubectl rollout restart deploy/mycc","handlingStrategy":"try-catch","validationCode":"// Before invoking, confirm the chaincode container is running and peer TLS config matches\n// kubectl get pods -l app=mycc   (container Running, no CrashLoopBackOff)\n// docker inspect mycc --format '{{.State.Status}}'","typeGuard":"func IsStreamRecvError(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"Recv() error\")\n}","tryCatchPattern":"err := contract.SubmitTransaction(\"createAsset\", \"a1\")\nif err != nil {\n    if IsStreamRecvError(err) {\n        // chaincode connection died before auth; redeploy/restart chaincode and retry once\n        restartChaincode(); err = contract.SubmitTransaction(\"createAsset\", \"a1\")\n    }\n    return err\n}","preventionTips":["Rebuild chaincode images whenever peer TLS certificates are rotated.","Set liveness checks so crashing chaincode containers are restarted automatically.","Verify chaincode-to-peer network reachability before deploying.","Watch chaincode container logs on startup for early exits."],"tags":["hyperledger-fabric","grpc","chaincode","stream"],"backgroundTag":"grpc-stream-recverror","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"}