hyperledger/fabric · error
Recv() error: , closing connection
Error message
Recv() error: %v, closing connection
What it means
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.
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.
Example fix
// before: peer TLS certs rotated but chaincode image still has old root certs; connection dies before REGISTER // after: rebuild chaincode image with current peer root certs # rebuild the chaincode image so its CA certs match the peer's current TLS CA docker build -t myorg/mycc:latest . && kubectl rollout restart deploy/mycc
Defensive patterns
Strategy: try-catch
Validate before calling
// Before invoking, confirm the chaincode container is running and peer TLS config matches
// kubectl get pods -l app=mycc (container Running, no CrashLoopBackOff)
// docker inspect mycc --format '{{.State.Status}}' Type guard
func IsStreamRecvError(err error) bool {
return err != nil && strings.Contains(err.Error(), "Recv() error")
} Try / catch
err := contract.SubmitTransaction("createAsset", "a1")
if err != nil {
if IsStreamRecvError(err) {
// chaincode connection died before auth; redeploy/restart chaincode and retry once
restartChaincode(); err = contract.SubmitTransaction("createAsset", "a1")
}
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- chaincode stream terminated
- First message needs to be a register
- request message is nil
- badly formatted message, cannot extract channel
- cannot collect files from empty chaincode path
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/7efcfc280bfc0e91.
Report an issue: GitHub.
Appendix: source
Thrown at core/chaincode/accesscontrol/interceptor.go:49
func newInterceptor(srv pb.ChaincodeSupportServer, auth authorization) pb.ChaincodeSupportServer {
return &interceptor{
next: srv,
auth: auth,
}
}
// Register makes the interceptor implement ChaincodeSupportServer
func (i *interceptor) Register(stream pb.ChaincodeSupport_RegisterServer) error {
is := &interceptedStream{
incMessages: make(chan *pb.ChaincodeMessage, 1),
stream: stream,
ServerStream: stream,
auth: i.auth,
}
msg, err := stream.Recv()
if err != nil {
return fmt.Errorf("Recv() error: %v, closing connection", err)
}
err = is.auth(msg, is.ServerStream)
if err != nil {
return err
}
is.incMessages <- msg
close(is.incMessages)
return i.next.Register(is)
}
type interceptedStream struct {
incMessages chan *pb.ChaincodeMessage
stream ChaincodeStream
grpc.ServerStream
auth authorization
}
// Send sends a chaincode messageView on GitHub (pinned to 2736b63f8f)