openimsdk/open-im-server · error

serve end

Error message

serve end

What it means

The gRPC server's Serve() call returned nil, meaning the server stopped serving without reporting an error (normally only after GracefulStop). Since a running server should never return normally, the code synthesizes a 'serve end' error and cancels the startup context.

Source

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

		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
		}

		go func() {
			err := rpcServer.Serve(rpcListener)
			if err == nil {
				err = fmt.Errorf("serve end")
			}
			cancel(fmt.Errorf("rpc %s %w", rpcRegisterName, err))
		}()
	}

	err = rpcFn(ctx, config, client, &grpcServiceRegistrar{onRegisterService: onGrpcServiceRegistrar})
	if err != nil {
		return err
	}
	<-ctx.Done()
	log.ZDebug(ctx, "cmd wait done", "err", context.Cause(ctx))
	if rpcGracefulStop != nil {
		timeout := time.NewTimer(time.Second * 15)
		defer timeout.Stop()
		select {
		case <-timeout.C:
			log.ZWarn(ctx, "rcp graceful stop timeout", nil)
		case <-rpcGracefulStop:

View on GitHub (pinned to 175a7bb067)

Solutions

  1. Inspect the logs for the sibling error that originally cancelled the context — 'serve end' is secondary
  2. Ensure nothing closes the rpcListener externally
  3. Check shutdown/GracefulStop wiring so the server isn't stopped during startup
Defensive patterns

Strategy: try-catch

Try / catch

if err := startrpc.Start(ctx, cfg); err != nil {
    if strings.Contains(err.Error(), "serve end") {
        log.Warn("grpc serve returned nil; look for the sibling error that cancelled the context")
    }
    return err
}

Prevention

When it happens

Trigger: rpcServer.Serve(rpcListener) returns nil — the listener was closed or GracefulStop was triggered while startup was still in progress (e.g. another component failed and cancelled ctx), or the listener is closed externally.

Common situations: Sibling RPC service in the same Start call failed, cancelling ctx and triggering GracefulStop; listener closed by another goroutine; shutdown racing startup.

Related errors


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