How to fix Error: HTTP 502 Bad Gateway (upstream server error) in Node.js
A 502 Bad Gateway error occurs when a reverse proxy server (like nginx or a load balancer) receives an invalid or no response from your Node.js application. This typically happens when your app crashes, times out, or fails to respond properly to incoming requests. Fixing this requires identifying why the upstream Node.js server is failing to respond.
Quick fix
Fixes 502
pm2 status- Verify your Node.js application is running
- Check your application logs for errors
- Verify port configuration matches between proxy and app
- Test direct access to bypass the proxy
pm2 statusError: HTTP 502 Bad Gateway (upstream server error)
What this error means
The 502 Bad Gateway error is an HTTP status code indicating that a server acting as a gateway or proxy received an invalid response from the upstream server. In Node.js deployments, this means your reverse proxy (nginx, Apache, or a cloud load balancer) tried to forward a request to your Node.js application, but the Node.js server either did not respond, crashed, responded with invalid data, or took too long to respond. The proxy server then returns this 502 error to the client because it cannot complete the request. This is distinct from a 504 Gateway Timeout, which specifically indicates the upstream server did not respond in time, whereas 502 can mean various types of invalid or missing responses.
Typical symptoms
- Users see "502 Bad Gateway" error page in their browser when accessing your application
- Nginx or load balancer error logs show "upstream prematurely closed connection" or "no live upstreams"
- Application works when accessed directly via localhost but fails through the reverse proxy
- Error occurs intermittently after the app has been running for a while
- Node.js process manager (PM2, systemd) shows the application has crashed or restarted
- High memory or CPU usage on the server before the error appears
- Requests timeout after a specific duration and then return 502
Common causes
- Node.js application has crashed or is not running, so the proxy cannot connect to it
- Port mismatch between what the proxy expects and what the Node.js app is actually listening on
- Node.js application is overloaded with traffic and cannot respond in time, causing the proxy to time out
- Request processing takes longer than the proxy timeout settings allow (default is often 60 seconds)
- Memory exhaustion causing Node.js to crash or become unresponsive
- Uncaught exceptions or unhandled promise rejections crashing the Node.js process
- Firewall blocking communication between the reverse proxy and Node.js application
- Protocol mismatch where nginx expects HTTP but Node.js is configured for HTTPS or vice versa
- HTTP request headers exceeding size limits set in the proxy configuration
How to fix "Error: HTTP 502 Bad Gateway (upstream server error)"
First, check if your Node.js process is actually running. If you use PM2, run:
pm2 statusFor systemd services:
sudo systemctl status your-app-nameIf the app is stopped or crashed, restart it:
pm2 restart app-name
# or
sudo systemctl restart your-app-nameIf the app keeps crashing, check the application logs to find the root cause.
Review logs to identify crashes or errors. For PM2:
pm2 logs app-name --lines 100For systemd:
sudo journalctl -u your-app-name -n 100 --no-pagerLook for uncaught exceptions, memory errors, or stack traces that indicate why the application crashed or stopped responding.
Ensure your Node.js app is listening on the port that your reverse proxy is forwarding to. Check your nginx configuration (usually in /etc/nginx/sites-available/):
location / {
proxy_pass http://localhost:3000; # Must match your Node.js port
}Verify your Node.js app is listening on that port:
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});Check which ports are in use:
sudo netstat -tlnp | grep nodeTry accessing your Node.js application directly to determine if the issue is with the proxy or the app itself:
curl http://localhost:3000If this works but accessing via the domain fails, the problem is with the reverse proxy configuration. If this also fails, the issue is with your Node.js application.
If your Node.js app takes time to process requests (database queries, API calls), increase the timeout values in your nginx configuration:
location / {
proxy_pass http://localhost:3000;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
proxy_send_timeout 300s;
}Test the configuration and reload nginx:
sudo nginx -t
sudo systemctl reload nginxMonitor your application's memory usage. If memory grows continuously, you have a memory leak:
pm2 monit
# or
top -p $(pgrep node)If memory usage is consistently high, increase the Node.js heap limit:
node --max-old-space-size=4096 app.jsFor PM2:
// ecosystem.config.js
module.exports = {
apps: [{
name: "app",
script: "./app.js",
node_args: "--max-old-space-size=4096"
}]
};Ensure your Node.js application handles errors gracefully:
// Catch uncaught exceptions
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception:', error);
// Log to monitoring service
process.exit(1); // Let PM2/systemd restart
});
// Catch unhandled promise rejections
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
process.exit(1);
});
// Graceful shutdown
process.on('SIGTERM', async () => {
console.log('SIGTERM received, closing server...');
await server.close();
process.exit(0);
});Use a process manager to automatically restart your app if it crashes. For PM2:
pm2 start app.js --name my-app --max-restarts 10For systemd, ensure restart is configured:
# /etc/systemd/system/your-app.service
[Service]
Restart=always
RestartSec=10Reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart your-appAdvanced notes
In production environments, 502 errors often occur during high traffic periods when the Node.js event loop becomes blocked or the application runs out of memory. Consider implementing horizontal scaling with multiple Node.js instances behind a load balancer using PM2 cluster mode or container orchestration. Monitor key metrics like event loop lag, memory usage, and response times using tools like PM2, New Relic, or DataDog. For applications deployed on cloud platforms (AWS, Google Cloud), check if the load balancer health checks are properly configured and that your Node.js app responds correctly to health check endpoints. Protocol mismatches are a common gotcha: if nginx is configured to use HTTP but your Node.js app only accepts HTTPS, or vice versa, you will get 502 errors. Large request headers (common with JWT tokens or many cookies) may exceed nginx default limits; increase client_header_buffer_size and large_client_header_buffers if needed. For WebSocket applications, ensure both the proxy and Node.js app have appropriate timeout settings and upgrade headers are properly configured.
Frequently asked questions
- What does "502" mean?
- The 502 Bad Gateway error is an HTTP status code indicating that a server acting as a gateway or proxy received an invalid response from the upstream server. js server either did not respond, crashed, responded with invalid data, or took too long to respond. The proxy server then returns this 502 error to the client because it cannot complete the request.
- How do I fix "502"?
- A 502 Bad Gateway error occurs when a reverse proxy server (like nginx or a load balancer) receives an invalid or no response from your Node.js application. This typically happens when your app crashes, times out, or fails to respond properly to incoming requests. Fixing this requires identifying why the upstream Node.js server is failing to respond.
- What causes "502"?
- Node.js application has crashed or is not running, so the proxy cannot connect to it Port mismatch between what the proxy expects and what the Node.js app is actually listening on Node.js application is overloaded with traffic and cannot respond in time, causing the proxy to time out
- Is the "502" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- ๐Node.js Official Documentation
- ๐Node.js process uncaughtException event(Official Docs)
- ๐Nginx proxy module documentation(Official Docs)
- ๐PM2 cluster mode documentation(Official Docs)
- ๐MDN 502 Bad Gateway documentation(Official Docs)