{"record":{"id":"ed76d27de9aef6af","repo":"openimsdk/open-im-server","slug":"rpc-register-s-w","errorCode":null,"errorMessage":"rpc register %s %w","messagePattern":"rpc register (.+?) %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/common/startrpc/start.go","lineNumber":246,"sourceCode":"\t\tif err != nil {\n\t\t\tcancel(fmt.Errorf(\"listen rpc %s %s %w\", rpcRegisterName, rpcListenAddr, err))\n\t\t\treturn\n\t\t}\n\n\t\trpcServer = grpc.NewServer(options...)\n\t\trpcServer.RegisterService(desc, impl)\n\t\trpcGracefulStop = make(chan struct{})\n\t\trpcPort := rpcListener.Addr().(*net.TCPAddr).Port\n\t\tlog.ZDebug(ctx, \"rpc start register\", \"rpcRegisterName\", rpcRegisterName, \"registerIP\", registerIP, \"rpcPort\", rpcPort)\n\t\tgrpcOpt := grpc.WithTransportCredentials(insecure.NewCredentials())\n\t\trpcGracefulStop = make(chan struct{})\n\t\tgo func() {\n\t\t\t<-ctx.Done()\n\t\t\trpcServer.GracefulStop()\n\t\t\tclose(rpcGracefulStop)\n\t\t}()\n\t\tif err := client.Register(ctx, rpcRegisterName, registerIP, rpcListener.Addr().(*net.TCPAddr).Port, grpcOpt); err != nil {\n\t\t\tcancel(fmt.Errorf(\"rpc register %s %w\", rpcRegisterName, err))\n\t\t\treturn\n\t\t}\n\n\t\tgo func() {\n\t\t\terr := rpcServer.Serve(rpcListener)\n\t\t\tif err == nil {\n\t\t\t\terr = fmt.Errorf(\"serve end\")\n\t\t\t}\n\t\t\tcancel(fmt.Errorf(\"rpc %s %w\", rpcRegisterName, err))\n\t\t}()\n\t}\n\n\terr = rpcFn(ctx, config, client, &grpcServiceRegistrar{onRegisterService: onGrpcServiceRegistrar})\n\tif err != nil {\n\t\treturn err\n\t}\n\t<-ctx.Done()\n\tlog.ZDebug(ctx, \"cmd wait done\", \"err\", context.Cause(ctx))","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/openimsdk/open-im-server/blob/175a7bb0673eca18e9d1b10bff4f728da6b1b513/pkg/common/startrpc/start.go#L228-L264","documentation":"After the listener is up, the service registers itself (name, IP, port) with service discovery via client.Register. If registration fails, startup is cancelled with 'rpc register <name>'. The gRPC server itself is fine; the service could not be announced to the registry.","triggerScenarios":"client.Register(ctx, rpcRegisterName, registerIP, port, grpcOpt) returns an error — registry (etcd/consul) unreachable, auth failure, or context already cancelled/expired.","commonSituations":"etcd endpoint misconfigured or down; wrong credentials/token; registerIP pointing at an invalid address; network partition between the service and the discovery cluster; slow startup exceeding the context deadline.","solutions":["Verify registry endpoints and connectivity (e.g. etcd health check)","Fix registerIP/rpcRegisterName configuration values","Check registry credentials and ACLs","Increase context timeout if startup races a slow registry"],"exampleFix":"// before\netcd:\n  rootPath: msg\n  addresses: [\"127.0.0.1:2379\"]\n// after\netcd:\n  rootPath: msg\n  addresses: [\"10.0.0.5:2379\", \"10.0.0.6:2379\"]","handlingStrategy":"retry","validationCode":"for _, ep := range cfg.Etcd.Addresses {\n    c, err := clientv3.New(clientv3.Config{Endpoints: []string{ep}, DialTimeout: 2 * time.Second})\n    if err != nil { return fmt.Errorf(\"registry %s unreachable: %w\", ep, err) }\n    c.Close()\n}","typeGuard":null,"tryCatchPattern":"err := startrpc.Start(ctx, cfg)\nif err != nil && strings.Contains(err.Error(), \"rpc register\") {\n    // backoff and retry registration / check registry health\n}","preventionTips":["Health-check etcd/registry before starting the service","Give startup a generous context deadline","Pin registry credentials via secrets, verify ACLs","Alert on registry availability in monitoring"],"tags":["grpc","service-discovery","registry","startup"],"backgroundTag":"service-registration-failed","analyzedSha":"175a7bb0673eca18e9d1b10bff4f728da6b1b513","analyzedAt":"2026-09-04T16:52:56.821Z","contentChangedAt":"2026-09-04T16:52:56.821Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}