# "502 Bad Gateway" after a deploy

> Your site answers 502 Bad Gateway after a deploy or a runtime switch. Your app is not answering the web server; here is how to find out why.

Source: https://veldhost.eu/docs/502-after-deploy

Last verified: 2026-11-13

**502 Bad Gateway** means nginx, the web server in front of your site, asked your app for the page and got no usable answer. The app is not running, not listening where nginx looks, or it crashed mid-request. It is most common on Node.js apps, right after a deploy, a version switch or a new start command.

## Why it happens

A Node.js app runs as a service of its own. nginx passes every request it cannot serve from `public/` to your app on the port in the `PORT` environment variable. A 502 follows when:

- **The app listens on the wrong port.** It listens on a fixed port, like `3000` or `8080`, instead of `process.env.PORT`.
- **The start command is wrong.** It points at a file the build did not produce, for example `node build` when the output is somewhere else.
- **The app crashes on start.** A dependency it needs at runtime sits in `devDependencies` (we install production dependencies only), or a required environment variable is missing. The service manager restarts a crashed app a few times in quick succession, then gives up. The app stays down until the next deploy, restart or switch.
- **The app ran out of memory** and was stopped. See ["Allowed memory size exhausted" / out of memory](https://veldhost.eu/docs/out-of-memory).
- **On a PHP site:** PHP itself is not running, for example straight after a PHP version switch that did not finish.

> **Note:** Every deploy checks your site right after the switch. A Node.js app must start and answer on its port, and the site must answer without a server error such as a 502. If it does not, the deploy fails at **Checking the site after the switch** and, when there is an earlier release, your site goes back to it. With no earlier release to go back to, the new code stays live and its row in **Recent deploys** reads *live, failing*. The check is one moment, though. An app that crashes a minute later, or only on some pages, still passes, so open the site yourself after each deploy.

## Fix it

1. **Read the app's own output.** Open [Sites](https://manage.veldhost.eu/portal/sites), choose your site, then **Logs** → **Application**. For a Node.js app, this is everything your app printed to the console, including the crash. Look for `Error: Cannot find module …`, `EADDRINUSE`, or a stack trace from your start-up code.
2. **Check what nginx saw.** In **Logs** → **Web server errors**, `connect() failed (111: Connection refused) while connecting to upstream` means nothing was listening. `upstream prematurely closed connection` means the app crashed while answering.
3. **Put the last good release back** while you fix it. If the deploy failed at **Checking the site after the switch** and says it switched your site back, this is already done. Otherwise, on the **Deploys** tab, use **Roll back to …** on the **Live now** strip. Your files return to the previous release and your database stays as it is. See [Approve a release, discard it or roll back](https://veldhost.eu/docs/release-approval-and-rollback).
4. **Check the port.** Your app must listen on `process.env.PORT`. In your app (Express): `app.listen(process.env.PORT || 3000)`.
5. **Check the start command.** Under **Configure** → **Node.js** → **Start command**, an empty field runs `npm start` (or `node server.js` / `node index.js`). Nuxt needs `node .output/server/index.mjs`. SvelteKit needs `node build`. Press **Save**; your app restarts with it within a minute. [Node.js apps](https://veldhost.eu/docs/node-apps) lists the commands per framework.
6. **Check dependencies.** Anything your app `require`s or `import`s at runtime must be in `dependencies`, not `devDependencies`. Commit an up-to-date `package-lock.json`.
7. **Start it again.** After a fix that needs no new code (an environment variable, say), press **Install & restart** in the **Deploys** tab's side panel. It installs production dependencies and restarts your app. For a fix in your code, push and deploy again.

On a PHP site, open **Configure** → **PHP version**, choose the version under **Run on** and press **Switch** again. Wait for **Now running PHP …**.

## Still stuck?

If **Application** is empty and **Web server errors** shows refused connections, your app never started at all. [Contact us](https://veldhost.eu/contact) with the site name and the time of the deploy, and we will look at the service on our side.

## Related

- [Node.js apps](https://veldhost.eu/docs/node-apps)
- [Reading your site logs](https://veldhost.eu/docs/site-logs)
- [White screen or "500 Internal Server Error"](https://veldhost.eu/docs/white-screen-or-500)
- [A deploy failed](https://veldhost.eu/docs/deploy-failed)