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
- Add enough entries to the rpcPorts config so every indexed RPC service has a port
- Set autoSetPorts=true (or the equivalent config flag) to let each service bind to an ephemeral port
- 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
- Keep rpcPorts length >= number of RPC services started per binary
- Validate config arrays at boot before binding listeners
- Prefer autoSetPorts in dynamic environments (K8s)
- Add a config lint test covering all service binaries
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.