openimsdk/open-im-server · error

listen rpc %s %s %w

Error message

listen rpc %s %s %w

What it means

The RPC server failed to bind its TCP listener on rpcListenAddr. net.Listen returned an error and startup is cancelled with 'listen rpc <name> <addr>'. It means the address/port could not be opened for the gRPC server.

Source

Thrown at pkg/common/startrpc/start.go:229

	onGrpcServiceRegistrar := func(desc *grpc.ServiceDesc, impl any) {
		if rpcServer != nil {
			rpcServer.RegisterService(desc, impl)
			return
		}
		var rpcListenAddr string
		if autoSetPorts {
			rpcListenAddr = net.JoinHostPort(listenIP, "0")
		} else {
			rpcPort, err := datautil.GetElemByIndex(rpcPorts, index)
			if err != nil {
				cancel(fmt.Errorf("rpcPorts index out of range %s %w", rpcRegisterName, err))
				return
			}
			rpcListenAddr = net.JoinHostPort(listenIP, strconv.Itoa(rpcPort))
		}
		rpcListener, err := net.Listen("tcp", rpcListenAddr)
		if err != nil {
			cancel(fmt.Errorf("listen rpc %s %s %w", rpcRegisterName, rpcListenAddr, err))
			return
		}

		rpcServer = grpc.NewServer(options...)
		rpcServer.RegisterService(desc, impl)
		rpcGracefulStop = make(chan struct{})
		rpcPort := rpcListener.Addr().(*net.TCPAddr).Port
		log.ZDebug(ctx, "rpc start register", "rpcRegisterName", rpcRegisterName, "registerIP", registerIP, "rpcPort", rpcPort)
		grpcOpt := grpc.WithTransportCredentials(insecure.NewCredentials())
		rpcGracefulStop = make(chan struct{})
		go func() {
			<-ctx.Done()
			rpcServer.GracefulStop()
			close(rpcGracefulStop)
		}()
		if err := client.Register(ctx, rpcRegisterName, registerIP, rpcListener.Addr().(*net.TCPAddr).Port, grpcOpt); err != nil {
			cancel(fmt.Errorf("rpc register %s %w", rpcRegisterName, err))
			return

View on GitHub (pinned to 175a7bb067)

Solutions

  1. Check what holds the port (ss -ltnp / lsof -i) and stop the conflicting process or pick a free port
  2. Correct listenIP in config to an IP actually present on the host
  3. Use a port above 1024 or grant the required privileges
  4. Verify rpcPorts values are unique across all services on the host

Example fix

// before
rpcPorts: [80, 10120]
// after
rpcPorts: [10110, 10120]
Defensive patterns

Strategy: try-catch

Validate before calling

addr := net.JoinHostPort(listenIP, strconv.Itoa(port))
if ln, err := net.Listen("tcp", addr); err != nil {
    return fmt.Errorf("port %s unavailable: %w", addr, err)
} else { ln.Close() }

Try / catch

err := startrpc.Start(ctx, cfg)
var oe *net.OpError
if errors.As(err, &oe) && errors.Is(oe.Err, syscall.EADDRINUSE) {
    // pick another port or abort with a friendly message
}

Prevention

When it happens

Trigger: net.Listen("tcp", rpcListenAddr) fails — typically because the port is already bound by another process, the IP is not assigned to the host, or the port is privileged/not permitted.

Common situations: Two services configured with the same port in rpcPorts; stale process still holding the port; listenIP set to an interface that doesn't exist in containers/K8s; port below 1024 without privileges.

Related errors


AI-assisted analysis of openimsdk/open-im-server@175a7bb067 (2026-09-04). Data as JSON: /api/errors/b289e3a0ee4c3061. Report an issue: GitHub.