RocketChat/Rocket.Chat · warning
Call to process.exit() timed out, aborting.
Error message
Call to process.exit() timed out, aborting.
What it means
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.
Source
Thrown at apps/meteor/server/meteor-methods/platform/restartServer.ts:30
};
}
}
Meteor.methods<ServerMethods>({
async restart_server() {
const uid = Meteor.userId();
if (!uid) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'restart_server' });
}
if ((await hasPermissionAsync(uid, 'restart-server')) !== true) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'restart_server' });
}
setTimeout(() => {
setTimeout(() => {
console.warn('Call to process.exit() timed out, aborting.');
process.abort();
}, 1000);
process.exit(1);
}, 1000);
return {
message: 'The_server_will_restart_in_s_seconds',
params: [2],
};
},
});
View on GitHub (pinned to b2c16d5842)
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.
Defensive patterns
Strategy: validation
Validate before calling
// Guard the client call: only offer in-app restart to permitted admins
import { Meteor } from 'meteor/meteor';
const canRestart = async () => {
if (!Meteor.userId()) throw new Meteor.Error('error-invalid-user', 'Invalid user');
return await Meteor.callAsync('hasPermission', 'restart-server'); // simplified
};
if (await canRestart()) Meteor.call('restart_server'); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/c704890359029311.
Report an issue: GitHub.