Express
Elastic Beanstalk
502 Bad Gateway
Deployment Issue
Node.js

502 Bad Gateway Deploying Express Generator Template on Elastic Beanstalk

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A 502 Bad Gateway on Elastic Beanstalk for an Express app usually means the reverse proxy is up but your Node process is not accepting requests correctly. Most cases come from port binding mistakes, startup command issues, or crash loops during boot. The fix is to make app startup deterministic and verify each layer from app logs to health checks.

Understand What 502 Means on Elastic Beanstalk

On Elastic Beanstalk, Nginx or Apache sits in front of your Node process. A 502 means the proxy could not reach a healthy upstream app process. That does not always mean your code is wrong. It often means runtime wiring is incomplete.

Typical causes:

  • App binds to a hardcoded port instead of process.env.PORT.
  • Procfile points to the wrong startup command.
  • App crashes on boot due to missing env variables.
  • Health check path returns non-success status.

Start diagnosis with platform logs.

bash
eb logs
eb health
eb status

Bind Express to the Environment Port

Express Generator templates are close to correct, but custom edits often break dynamic port handling. Ensure your server listens on the port assigned by Elastic Beanstalk.

javascript
1// app.js
2const express = require('express');
3const app = express();
4
5app.get('/health', (req, res) => {
6  res.status(200).json({ ok: true });
7});
8
9const port = process.env.PORT || 3000;
10app.listen(port, () => {
11  console.log(`Listening on port ${port}`);
12});

If you bind to a fixed port like 3000 in a config file and ignore process.env.PORT, the proxy may fail to route traffic correctly.

Define a Reliable Startup Command

Elastic Beanstalk should know exactly how to launch your app. Add a Procfile in project root.

text
web: npm run start

Then ensure package.json start script is valid for production.

json
1{
2  "name": "eb-express-app",
3  "version": "1.0.0",
4  "scripts": {
5    "start": "node app.js"
6  },
7  "dependencies": {
8    "express": "^4.19.2"
9  }
10}

Avoid dev-only commands in production startup, such as tools that are not installed on deploy instances.

Check Runtime and Environment Configuration

A mismatched Node version can cause boot failure even before first request. Pin runtime in your project config and verify required env variables are present.

json
1{
2  "engines": {
3    "node": "20.x"
4  }
5}

Set variables with EB CLI or console.

bash
eb setenv NODE_ENV=production API_BASE_URL=https://api.example.com

If your app expects secrets and they are missing, process startup can fail silently unless logs are reviewed.

Validate Health Check Endpoint

If default health path does not match your app behavior, use a dedicated lightweight route such as /health. It should return success without dependency-heavy work.

javascript
app.get('/health', (req, res) => {
  res.status(200).send('ok');
});

Then configure health check path in environment settings if needed. A fast health endpoint reduces false unhealthy states during load or cold startup.

Practical Recovery Workflow

Use a consistent recovery workflow when 502 appears:

  1. Check eb health for overall status.
  2. Pull logs and confirm app process started.
  3. Verify port binding and Procfile command.
  4. Confirm environment variables and Node runtime.
  5. Redeploy and retest health endpoint.

A repeatable sequence avoids guessing and shortens incident time.

Add Startup Validation During Deploy

A fast startup validation script can fail deploy early when environment assumptions are missing. This is better than waiting for proxy failures after instance boot.

javascript
1// scripts/check-startup.js
2const required = ['PORT'];
3const missing = required.filter(key => !process.env[key]);
4
5if (missing.length > 0) {
6  console.error('Missing environment keys:', missing.join(', '));
7  process.exit(1);
8}
9
10console.log('startup validation passed');

Call it from your start command or prestart script.

json
1{
2  "scripts": {
3    "prestart": "node scripts/check-startup.js",
4    "start": "node app.js"
5  }
6}

This catches config drift early and produces clear errors in logs.

Verify Health Path and Process Binding Locally

Before deployment, simulate production startup locally with environment variables and health checks.

bash
PORT=8080 NODE_ENV=production npm start
curl -i http://127.0.0.1:8080/health

If local run fails under production-style env vars, Elastic Beanstalk will fail too. This small preflight step prevents many avoidable 502 incidents.

Common Pitfalls

  • Hardcoding app port instead of reading process.env.PORT.
  • Using missing or wrong startup command in Procfile.
  • Shipping without required environment variables.
  • Pointing health check to expensive endpoints that fail under warmup.

Summary

  • 502 on Elastic Beanstalk often means upstream app process is unavailable.
  • Bind Express to process.env.PORT and define clear startup command.
  • Validate runtime version and environment variables before redeploy.
  • Use a simple health endpoint and check logs first during incidents.

Course illustration
Course illustration

All Rights Reserved.