openimsdk/open-im-server · error

rpcPorts index out of range %s %w

Error message

rpcPorts index out of range %s %w

What it means

During RPC server startup, when autoSetPorts is disabled, the service picks its port from the rpcPorts list by its index. datautil.GetElemByIndex returns an error when index exceeds the list length, and startup is cancelled with 'rpcPorts index out of range'. It means the configured rpcPorts array is shorter than the number of RPC services being started.

Source

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

	}

	var (
		rpcServer       *grpc.Server
		rpcGracefulStop chan struct{}
	)

	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() {

View on GitHub (pinned to 175a7bb067)

Solutions

  1. Add enough entries to the rpcPorts config so every indexed RPC service has a port
  2. Set autoSetPorts=true (or the equivalent config flag) to let each service bind to an ephemeral port
  3. Verify the number of RPC services started matches the number of configured ports

Example fix

// before (config)
rpcPorts: [10110]
// after (two RPC services)
rpcPorts: [10110, 10111]
Defensive patterns

Strategy: validation

Validate before calling

if !autoSetPorts && len(rpcPorts) <= index {
    return fmt.Errorf("rpcPorts must contain at least %d entries, got %d", index+1, len(rpcPorts))
}

Try / catch

if err := startrpc.Start(ctx, cfg); err != nil {
    if strings.Contains(err.Error(), "rpcPorts index out of range") {
        // fix config and retry or exit with clear message
    }
    return err
}

Prevention

When it happens

Trigger: Calling startrpc.Start with autoSetPorts=false and an rpcPorts config slice shorter than the number of RPC services being registered (index >= len(rpcPorts)).

Common situations: Config file omits or truncates the rpcPorts list while multiple RPC services are launched; a new RPC service was added to the binary but the ops-supplied rpcPorts array was not extended; mismatched config versions between nodes.

Related errors


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