Exit code 143 means your process received SIGTERM—a graceful termination signal. This happens during Docker stops, Kubernetes pod termination, or CI timeouts. Run Node.js directly instead of through npm to handle signals properly.
Fixes ELIFECYCLE
# Instead of:
CMD ["npm", "start"]
# Use:
CMD ["node", "server.js"]# Instead of:CMD ["npm", "start"]# Use:CMD ["node", "server.js"]npm ERR! code ELIFECYCLEnpm ERR! errno 143npm ERR! Exit status 143
Exit code 143 is calculated as 128 + 15 (SIGTERM signal number). It means your process received a termination signal—typically a graceful shutdown request from the system. This commonly occurs when: - Docker stops a container (`docker stop`) - Kubernetes terminates a pod - A CI/CD system times out a job - A process manager restarts your app The "problem" is that npm doesn't properly forward SIGTERM to your Node.js process. Instead, npm catches the signal and kills its children immediately, resulting in exit code 143 rather than a graceful shutdown.
The root cause is npm not forwarding signals properly. In production:
# Instead of:
CMD ["npm", "start"]
# Use:
CMD ["node", "server.js"]This makes Node.js the top-level process, allowing it to handle SIGTERM directly.
Handle SIGTERM at the very top of your entry file:
process.on('SIGTERM', () => {
console.log('SIGTERM received, shutting down gracefully');
// Close database connections, finish requests, etc.
server.close(() => {
process.exit(0);
});
});Place this before any blocking operations.
npm is not designed for production process management. Use:
# PM2
pm2 start server.js
# Or run directly
node server.jsProcess managers handle signals properly and provide restart capabilities.
Kubernetes sends SIGTERM, then waits (default 30s) before SIGKILL:
spec:
terminationGracePeriodSeconds: 60Ensure your app can shut down within this window.
Docker's default stop timeout is 10 seconds:
# Increase timeout
docker stop --time=30 container_nameOr in docker-compose.yml:
services:
app:
stop_grace_period: 30sSignal exit codes:
- 130 (128+2): SIGINT (Ctrl+C)
- 137 (128+9): SIGKILL (forced termination, no grace period)
- 143 (128+15): SIGTERM (graceful termination request)
If you see 137 instead of 143, your process didn't shut down in time and was forcefully killed.
For Node.js apps, a proper graceful shutdown includes:
const server = app.listen(3000);
process.on('SIGTERM', () => {
console.log('SIGTERM received');
server.close(() => {
console.log('HTTP server closed');
// Close database connections
db.close(() => {
console.log('Database connection closed');
process.exit(0);
});
});
// Force close after 30s
setTimeout(() => {
console.error('Forced shutdown');
process.exit(1);
}, 30000);
});