{"record":{"id":"c704890359029311","repo":"RocketChat/Rocket.Chat","slug":"call-to-process-exit-timed-out-aborting","errorCode":null,"errorMessage":"Call to process.exit() timed out, aborting.","messagePattern":"Call to process\\.exit\\(\\) timed out, aborting\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"apps/meteor/server/meteor-methods/platform/restartServer.ts","lineNumber":30,"sourceCode":"\t\t};\n\t}\n}\n\nMeteor.methods<ServerMethods>({\n\tasync restart_server() {\n\t\tconst uid = Meteor.userId();\n\n\t\tif (!uid) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'restart_server' });\n\t\t}\n\n\t\tif ((await hasPermissionAsync(uid, 'restart-server')) !== true) {\n\t\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'restart_server' });\n\t\t}\n\n\t\tsetTimeout(() => {\n\t\t\tsetTimeout(() => {\n\t\t\t\tconsole.warn('Call to process.exit() timed out, aborting.');\n\t\t\t\tprocess.abort();\n\t\t\t}, 1000);\n\t\t\tprocess.exit(1);\n\t\t}, 1000);\n\n\t\treturn {\n\t\t\tmessage: 'The_server_will_restart_in_s_seconds',\n\t\t\tparams: [2],\n\t\t};\n\t},\n});\n","sourceCodeStart":12,"sourceCodeEnd":42,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/platform/restartServer.ts#L12-L42","documentation":"Emitted by the 'restart_server' Meteor method in apps/meteor/server/meteor-methods/platform/restartServer.ts. After permission checks, it schedules process.exit(1) after 1s; a nested setTimeout arms a watchdog 1s later. If the process has still not exited by then (something is keeping the Node event loop alive — open handles, non-daemon timers, hung connections), the watchdog prints this warning and calls process.abort() (SIGABRT) to force-kill the server. The method returns 'The_server_will_restart_in_s_seconds' with params [2] to the caller.","triggerScenarios":"An authenticated admin with the 'restart-server' permission calls Meteor.call('restart_server'). The exit proceeds normally and the warning never appears. It only appears when process.exit(1) cannot complete within ~1s because pending async work (long-running method invocations, open MongoDB/Redis handles, custom integrations) keeps the event loop draining — then the watchdog aborts the process.","commonSituations":"Pressing 'Restart server' in Admin -> Info on a heavily loaded instance; deployments with apps or custom code that hold long-lived connections; older Rocket.Chat versions where shutdown hooks were slow; Docker/Kubernetes setups where the in-app restart is used instead of the orchestrator. The restart itself still happens (via abort), but it is not graceful, so in-flight requests can be dropped.","solutions":["Treat this as a symptom, not the bug: inspect what keeps the event loop alive (custom apps, integrations, hung DDP connections) and fix/close them so shutdown is fast.","Prefer restarting via your process manager (systemctl restart, docker restart, kubectl rollout restart) instead of the in-app method — orchestrators give you a clean, supervised restart.","Upgrade Rocket.Chat: newer builds have faster, more deterministic shutdown paths.","If you must use the in-app restart, do it during a maintenance window when traffic and background jobs (LDAP sync, push, emails) are idle."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Guard the client call: only offer in-app restart to permitted admins\nimport { Meteor } from 'meteor/meteor';\n\nconst canRestart = async () => {\n  if (!Meteor.userId()) throw new Meteor.Error('error-invalid-user', 'Invalid user');\n  return await Meteor.callAsync('hasPermission', 'restart-server'); // simplified\n};\n\nif (await canRestart()) Meteor.call('restart_server');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer orchestrator-level restarts (systemd/docker/k8s) over the in-app restart_server method; they do not depend on Node's exit path.","Close long-lived connections and avoid non-cancellable background work in custom apps so process.exit() completes within the 1s watchdog.","Trigger in-app restarts only at low-traffic moments so the potential process.abort() fallback drops nothing important."],"tags":["process-shutdown","restart","meteor-methods","process-exit","watchdog"],"backgroundTag":"graceful-shutdown-timeout","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}