502 Bad Gateway on a Node or Next.js site on a VPS

A 502 is the web server, usually nginx, saying that it passed the request to your application and nothing answered. The app is a Node process that someone started once, on a VPS nobody watches, and it stopped. That is the most common outage on Node and Next.js sites, and the fix is rarely in the code.

What a 502 means

nginx forwards each request to the app on a local port, 3000 by default. When the app process is dead, listening on a different port, or still starting, nginx gives up and shows 502 Bad Gateway. The site is not hacked and the server is not down; one process is.

The usual causes

  • The server rebooted, for an update or by the host, and the app was never set to start on boot. It ran for months because nobody rebooted.
  • The process ran out of memory. Small servers with one or two gigabytes run Node and a build in the same memory, and the kernel kills the biggest process.
  • An uncaught error on one request crashed the process. A process manager restarts it; without one, it stays dead.
  • A deploy failed part way: the build stopped on an error, a setting such as an API key was missing from the environment, or a dependency did not install.
  • The Node version changed and the app or one of its packages no longer runs on it.
  • The disk filled up with logs or old builds, and nothing can write any more.

How to see for yourself

  • If the app runs under pm2, "pm2 list" shows whether it is online, and "pm2 logs" shows why it stopped. Under systemd, "systemctl status" and "journalctl -u" do the same.
  • nginx writes the failure to its error log, usually /var/log/nginx/error.log, as "connect() failed (111: Connection refused) while connecting to upstream". That line confirms the app, not nginx, is the problem.
  • "free -m" shows memory and "df -h" shows disk. A server with no free memory or a full disk explains everything else.

Why it comes back and then dies again

Restarting the process hides the cause. If it was memory, it will run out again at the next busy moment; if it was a request that crashes the app, the next visitor to that page kills it. The fix is reading the log for the real cause, then giving the app a process manager that restarts it, a start-on-boot rule, a memory limit it can live within, and swap space on a small server. Hosted platforms such as Vercel and Netlify do not fail this way; a failed build there is a different problem and shows in their dashboard.

When to hand it to us

The site-down fix is the same price for a Node site. It needs SSH, which the job page walks you through with our per-job key. We find the cause in the logs, bring the app up, set it to survive the next reboot and the next crash, and the report says what happened and what we changed.

Questions people ask

Will a reboot fix it?
Sometimes for a while, and sometimes it makes it worse, because an app that is not set to start on boot stays down after the reboot. Find the cause first.
My site is on Vercel or Netlify, not a VPS. Same problem?
No. Those platforms rebuild the site on every deploy, and a failure shows as a failed build in their dashboard, usually a missing setting or a code error. We can look, and the fix is in the code or the settings, not on a server.
Can you upgrade Node while you are in there?
If the app and its packages support the newer version, yes, and the report says so. If not, we pin the version it needs and tell you what an upgrade would take.