SIGTERM errors in npm occur when a process is terminated externally, often by Docker, CI timeouts, or process managers. Run Node directly instead of via npm for proper signal handling.
SIGTERM (signal 15) is a termination signal sent to gracefully shut down a process. When npm reports this error, it means an external system (Docker, Kubernetes, CI/CD, or a process manager) sent SIGTERM to your npm process. The issue is that npm doesn't properly forward SIGTERM signals to child processes. When npm receives SIGTERM, it often kills child processes immediately without allowing graceful shutdown handlers to execute. This is a known limitation of running Node.js applications via npm scripts.
The best fix—bypass npm's signal handling issues:
Before (problematic):
CMD ["npm", "start"]After (correct):
CMD ["node", "index.js"]This makes your Node.js process PID 1, ensuring it receives signals directly.
Handle SIGTERM in your code for graceful shutdown:
// At the top of your entry file
process.on('SIGTERM', async () => {
console.log('SIGTERM received, shutting down gracefully');
// Close server
await server.close();
// Close database connections
await db.disconnect();
process.exit(0);
});
process.on('SIGINT', async () => {
console.log('SIGINT received, shutting down gracefully');
await server.close();
process.exit(0);
});Ensure your process receives signals in Docker:
Shell form (bad—signals go to shell, not Node):
CMD npm startExec form (good—Node receives signals):
CMD ["node", "index.js"]Or use ENTRYPOINT:
ENTRYPOINT ["node", "index.js"]Use Node directly in your Procfile:
Before:
web: npm startAfter:
web: node index.jsPrevent duplicate signal handling:
// Use once() instead of on() to handle only first signal
process.once('SIGTERM', shutdownHandler);
process.once('SIGINT', shutdownHandler);
async function shutdownHandler() {
console.log('Shutting down...');
// Cleanup code
process.exit(0);
}npm can sometimes send signals twice; once() prevents double execution.
For production deployments, use a proper process manager:
# PM2
pm2 start index.js
# Or in ecosystem.config.js
module.exports = {
apps: [{
name: 'app',
script: 'index.js',
kill_timeout: 5000
}]
}Process managers handle signals correctly and provide additional features like clustering.
This issue became more prominent in Node.js 20.3.0+ due to changes in how npm handles signals. If you must use npm scripts, consider downgrading npm or Node.js version temporarily while the npm team addresses this.
For Kubernetes, set appropriate termination grace periods:
spec:
terminationGracePeriodSeconds: 30The graceful-shutdown npm package can help manage shutdown across different environments with various cleanup requirements.
npm ERR! code ENOAUDIT npm ERR! Audit endpoint not supported
How to fix "npm ERR! code ENOAUDIT - Audit endpoint not supported"
npm ERR! code EBADDEVENGINES npm ERR! devEngines.runtime incompatible with current node version
How to fix "npm ERR! code EBADDEVENGINES - devEngines.runtime incompatible with current node version"
npm ERR! code ETOOMANYARGS npm ERR! Too many arguments
How to fix "npm ERR! code ETOOMANYARGS - Too many arguments"
npm ERR! code EINVALIDTAGNAME npm ERR! Invalid tag name: tag names cannot contain spaces
How to fix "npm ERR! code EINVALIDTAGNAME - tag names cannot contain spaces"
npm ERR! code E400 npm ERR! 400 Bad Request
How to fix "npm ERR! code E400 - 400 Bad Request" error