EthioDeploy
PricingDocsBlogAbout
Start free
0.0.0.0:$PORT

Fix deploy errors · October 29, 2026

502 Bad Gateway after deploy: bind to 0.0.0.0 and $PORT

By Brook Solomon, Founder, EthioDeploy

A 502 right after a deploy almost always means the platform's proxy can't reach your app. The app is listening on 127.0.0.1 instead of 0.0.0.0, or on a hard-coded port instead of the one in the PORT environment variable. Bind to 0.0.0.0 and read PORT, and the 502 goes away.

Why does my app return 502 after deploy when it works locally?

Because the proxy in front of your app can't connect to it. On your laptop you open localhost:5000 from the same machine, so an app listening on 127.0.0.1 works fine. On a hosting platform, requests arrive from a proxy in another container or machine. An app bound to 127.0.0.1 only accepts connections from itself, so the proxy gets nothing back and returns 502.

The second cause is the port. Platforms tell your app which port to use through the PORT environment variable. An app that always listens on 5000 or 8000 is running, just not where the proxy is looking.

Every major platform documents the same rule:

  • Render: “Every Render web service must bind to a port on host 0.0.0.0 to serve HTTP requests.” Its default PORT is 10000.
  • Railway says the most common reason for “Application failed to respond” is that the app “is not listening on the correct host or port.”
  • Heroku assigns the port as PORT and kills a web process that hasn't bound to it within 60 seconds (error R10, which then shows up as H10 App crashed).

What host and port does my framework use by default?

Most development servers default to 127.0.0.1 on purpose, so your work-in-progress isn't reachable from the network. That default is what breaks in production.

ServerDefault hostDefault portReads PORT?
Node server.listen, ExpressAll interfacesNone, you pass itOnly if your code does
Next.js next start0.0.0.03000Yes
Vite vite previewlocalhost4173No
uvicorn127.0.0.18000No
gunicorn127.0.0.1, or 0.0.0.0 when PORT is set8000Yes
Flask flask run127.0.0.15000No
Django runserver127.0.0.18000No
Go ListenAndServe(":8080")All interfacesThe one in the stringOnly if your code does
Rails rails serverlocalhost in development, 0.0.0.0 otherwise3000Yes

How do I fix it in my framework?

Read the port from the environment and listen on all interfaces. The start commands:

# Node / Express
app.listen(process.env.PORT || 3000, "0.0.0.0")

# FastAPI, Starlette (uvicorn)
uvicorn main:app --host 0.0.0.0 --port $PORT

# Flask, Django (gunicorn binds 0.0.0.0:$PORT on its own when PORT is set)
gunicorn app:app
gunicorn myproject.wsgi

# Vite static preview
vite preview --host 0.0.0.0 --port $PORT --strictPort

# Go
http.ListenAndServe(":"+os.Getenv("PORT"), nil)

Three gotchas that look like a 502 but aren't a missing host:

  • Next.js can't take PORT from a .env file. Its docs say the HTTP server boots before .env is read. Set PORT in the platform's environment instead.
  • Vite moves to the next free port when the one you asked for is busy. Add --strictPort so it fails loudly instead of listening somewhere else.
  • Django's runserver and Flask's flask run are development servers. Their docs say not to use them in production. Run gunicorn instead.

What happens on EthioDeploy?

EthioDeploy sets PORT=3000 and HOSTNAME=0.0.0.0 for every web service, and overrides any value you set for those two. Then every deploy waits for a health check: a GET to / that has to return a 2xx or 3xx status within 30 seconds.

If the app never answers, the deploy fails and your previous version keeps serving traffic, so a wrong bind never takes the site down. The build log says what went wrong:

Health check timed out after 30000ms. The app never answered on port $PORT.
Make sure it listens on 0.0.0.0 and reads the PORT env var.

If your home page needs a login or returns 404 by design, set a Health Check Path such as /healthz in Settings. The framework guides list the exact start command for each stack: Express, FastAPI, Django, Flask and Go.

Questions

What does binding to 0.0.0.0 mean?

It tells the server to accept connections on every network interface of the machine. 127.0.0.1 only accepts connections from the same machine, so a proxy running elsewhere can't reach it.

Is listening on 0.0.0.0 a security risk?

Not inside a container on a hosting platform. The container only receives traffic the platform's proxy sends it. On your own laptop or a server with a public IP, 0.0.0.0 does expose the app to the network, which is why development servers default to 127.0.0.1.

Why does my app work locally but not after deploy?

Locally you connect from the same machine, so 127.0.0.1 and a fixed port work. After deploy the platform's proxy connects from outside the app and expects the port in the PORT environment variable.

What port should my app listen on?

The one in the PORT environment variable. Each platform picks its own: Render's default is 10000, Heroku assigns one per dyno, and EthioDeploy sets 3000. Reading PORT works on all of them.

What is Heroku error H10 App crashed?

Heroku shows H10 when a web dyno crashed or timed out while booting. A common cause is error R10: the process didn't bind to $PORT within 60 seconds of starting.

Sources

Checked on October 29, 2026:

  • Render: Web services, port binding
  • Railway: Application failed to respond
  • Heroku: Error codes (R10, H10)
  • Node.js: server.listen
  • Next.js: CLI
  • Vite: Preview options
  • Uvicorn: Settings
  • Gunicorn: bind setting
  • Flask: API, Flask.run
  • Django: runserver
  • Go: net/http
  • Rails: Command line guide

Push a repo. Get a URL.

  • Deploy an Express app
  • Deploy a FastAPI app
  • Troubleshooting deploys
Start free

On this page

  • Why does my app return 502 after deploy when it works locally?
  • What host and port does my framework use by default?
  • How do I fix it in my framework?
  • What happens on EthioDeploy?
  • Questions
  • Sources

Topics

  • Fix deploy errors2
  • Hosting and pricing1
  • Building from Ethiopia1

Deploy guides

  • Deploy a Next.js app
  • Deploy a Django app
  • Deploy a FastAPI app
  • Deploy a Laravel app
  • Deploy a Lovable app
All guides →

Written by

BSBrook SolomonFounder, EthioDeploy

More in Fix deploy errors

  • VITE_*

    FIX DEPLOY ERRORS · OCT 29

    Vite env variables undefined in production: causes and fixes

Product

  • Pricing
  • Documentation
  • AI coding agent
  • Agent mode docs
  • Domains
  • Hosting in Ethiopia

Deploy guides

  • Next.js
  • Node.js
  • Python
  • SvelteKit
  • Django
  • FastAPI
  • Flask
  • Express
  • Laravel
  • Go
  • Lovable
  • Bolt
  • Replit
  • v0
  • Google AI Studio
  • Base44
  • Firebase Studio
  • Claude Code & Cursor

Compare

  • EthioDeploy vs Heroku
  • EthioDeploy vs Vercel
  • EthioDeploy vs Render
  • EthioDeploy vs Railway
  • EthioDeploy vs Fly.io
  • EthioDeploy vs Netlify
  • Heroku alternatives
  • Vercel alternatives
  • Netlify alternatives
  • Render alternatives
  • Railway alternatives

Company

  • About
  • Blog
  • Support
  • Contact
  • Terms
  • Privacy

EthioDeploy: agentic first development and deployment, started in Ethiopia, built for developers everywhere.