MeatButton

Nginx 502 Bad Gateway: What It Means and How to Fix It

For anyone who deployed an app and is seeing 502 errors

You deployed your app. Maybe you built it with an AI tool like Bolt or Lovable. Maybe you followed a tutorial. Either way, you go to your site and instead of your app, you see:

502 Bad Gateway — nginx

You Google it. You try things. You ask ChatGPT. It tells you to restart Nginx. You restart Nginx. Same error. Now you're 45 minutes in with nothing to show for it.

Here's what's actually going on.

What "502 Bad Gateway" actually means

Think of your setup as a restaurant. Nginx is the front door and the host stand. Your app (Node, Python, Rails, whatever) is the kitchen.

When someone visits your site, they walk up to the front door (Nginx). Nginx says "great, let me send your order to the kitchen." It turns around to pass the request to your app and... nobody's there. The kitchen is closed. Or the kitchen is in a different building than where Nginx is looking. Or the kitchen is so backed up it stopped answering.

502 means Nginx tried to reach your app and couldn't. The problem is almost never Nginx itself. The problem is your app.

The most common causes

1. Your app crashed and isn't running

This is the most common cause by far. Your app started, hit an error, and died. Nginx is still running because Nginx is solid. But it has nothing to forward requests to.

Signs: The 502 happens on every page, every time, no exceptions.

2. Your app is running on a different port than Nginx expects

Your Nginx config says "send traffic to port 3000." Your app is actually running on port 8000. Nginx sends the request to port 3000, nobody answers, 502.

This happens a lot when AI writes your config. It picks a port number that's common (like 3000) but doesn't check what port your app actually uses. Or your app has a default port in its code and the AI's Nginx config assumes a different one.

Signs: Your app seems to be running (you can see it in the process list), but you still get 502.

3. Your app takes too long to start or respond

Some apps, especially Python/ML apps or anything loading a big model, take 30+ seconds to start. Nginx has a timeout (usually 60 seconds). If your app doesn't respond in time, Nginx gives up and returns 502.

Signs: The 502 shows up right after a deploy or restart, but if you wait a minute and refresh, it sometimes works.

4. Socket or permissions issue

If your app talks to Nginx through a Unix socket instead of a port (this is common with Python apps using Gunicorn or uWSGI), the socket file might not exist, or Nginx might not have permission to read it. Same result: Nginx can't connect, 502.

Signs: The Nginx error log mentions "connect() failed" or "permission denied" with a path to a .sock file.

What to try

Step 1: Check if your app is actually running

SSH into your server and run:

systemctl status your-app-name

If you don't know the service name, try:

ps aux | grep node
ps aux | grep python
ps aux | grep gunicorn

If nothing comes up, your app isn't running. That's your problem. Try starting it and look at the error output to see why it crashed.

Step 2: Check the Nginx error log

sudo tail -50 /var/log/nginx/error.log

This log tells you exactly what Nginx tried to do and what went wrong. You'll see messages like:

This log is worth more than any advice an AI can give you. Read it.

Step 3: Make sure the ports match

Open your Nginx config:

sudo cat /etc/nginx/sites-enabled/default

Look for a line like proxy_pass http://localhost:3000; or proxy_pass http://127.0.0.1:8000;. That port number needs to match the port your app is actually listening on. Check your app's startup output or config file to confirm.

If they don't match, fix the Nginx config and reload:

sudo nginx -t
sudo systemctl reload nginx

Step 4: Restart your app, not Nginx

Nine times out of ten, you need to restart your app, not Nginx. Nginx is just the messenger. Restarting it when the problem is your app does nothing.

sudo systemctl restart your-app-name

Then check the status again to make sure it actually stayed running. Apps that crash on startup will show "active" for a split second and then die. Watch it for a few seconds.

Why AI makes this worse

If you ask ChatGPT or Claude to fix a 502 error, here's what usually happens:

  1. It tells you to restart Nginx. That doesn't fix it because Nginx isn't the problem.
  2. It generates a new Nginx config file. The new config has a different port number, or a different format, or extra directives you don't need. Now you have a config you don't understand that still doesn't work.
  3. It suggests increasing timeouts. This is sometimes right but usually a bandaid. Your app is crashing, and making Nginx wait longer for a crashed app doesn't help.
  4. It never asks what your app is, what port it runs on, or whether it's actually running. It just pattern-matches "502" and spits out generic fixes.

The fundamental problem: the AI can't see your server. It can't run systemctl status. It can't read your Nginx error log. It can't check what's actually listening on which port. So it guesses. And each guess that doesn't work sends you further from the answer, not closer to it.

A human engineer would SSH in, check the log, see the problem, and fix it. Five minutes, one pass, done.

Still seeing 502?

Install MeatButton. Press it from inside ChatGPT or Claude and a real expert will look at your actual server, read the actual logs, and fix the actual problem. First one's free.

Get MeatButton