Replit deployment failed: fix the port and 0.0.0.0 errors
Short answer
- Your server must listen on 0.0.0.0, not localhost or 127.0.0.1, and should use the PORT environment variable.
- If .replit has a [[ports]] section, automatic port detection is off: map your server's localPort to externalPort 80, and expose only one external port.
- Replit checks your homepage before the app goes live. If / takes more than about five seconds to answer, publishing can fail at the last step.
Your app runs fine in the Replit preview, you hit Publish, and the build succeeds. Then it fails at the very last step, or the live URL says Application failed to respond. In most cases the code is fine. The problem is how the server is bound to its host and port, and how fast it answers Replit's health check. This guide walks through the checks in the order that fixes the most apps.
Symptoms
- Publishing fails during the promote step, after the build has finished.
- Deployment logs show
healthcheck failedorcontext deadline exceeded. - The live URL shows Application failed to respond or a blank error page, while the preview works.
- A warning in the publishing settings about multiple ports, or about a port bound to localhost.
Likely causes
- The server listens on
localhostor127.0.0.1. That works in the workspace but not in a published app. - The port is hard-coded to a value that does not match the
[[ports]]mapping in.replit. .replitexposes several external ports. Autoscale and Reserved VM deployments support a single external port.- The homepage is slow at startup (database seeding, cache warm-up, big imports) and misses the health check window.
- The run command starts a dev server or a one-shot script instead of a long-running production server.
Step-by-step fix
1. Bind to 0.0.0.0 and read PORT
Replit's own docs are explicit: a published app must listen on 0.0.0.0. Read the port from the environment and keep a fallback for the workspace.
// Node.js / Express
const PORT = Number(process.env.PORT) || 5000;
app.listen(PORT, "0.0.0.0", () => console.log(`listening on ${PORT}`));# Python
uvicorn main:app --host 0.0.0.0 --port ${PORT:-8000}
gunicorn --bind 0.0.0.0:${PORT:-8000} app:app
2. Check the [[ports]] section in .replit
If .replit lists ports, Replit stops detecting the port for you. You need exactly one entry with externalPort = 80, and its localPort must be the port your server really uses.
[[ports]]
localPort = 5000
externalPort = 80Delete the externalPort lines of any other port (a second dev server, a debugger, a websocket helper). Extra exposed ports are a common reason Autoscale publishing fails.
3. Make the homepage answer fast
Before marking the app live, Replit sends an HTTP request to your homepage. If it takes longer than about five seconds, publishing can fail. Start listening first, then do slow work: run migrations in the build step, load caches lazily, and never seed data inside the request for /.
4. Confirm the run command
Open the publishing settings and read the run command. It should start the production server (for example npm run start or node dist/index.js) after the build command (npm run build). A dev command such as npm run dev can start a dev server on a different port. A command that exits after running a script leaves nothing to answer the health check.
5. Read the deployment logs, then republish
Open the failed deployment's logs from the Publishing pane and find the first error line. A crash during startup (a missing secret, a failed import) looks exactly like a port problem from the outside. Fix it, then publish again.
Copy-paste prompt for Replit Agent
Open a new Agent chat (a fresh chat keeps old attempts out of its context) and paste this:
My Replit app works in Preview but publishing fails (promote step / health check / "Application failed to respond").
Please check the publishing setup only, without changing app features:
1. Make the server listen on 0.0.0.0 and use process.env.PORT with a fallback.
2. Open .replit and keep exactly one [[ports]] entry with externalPort = 80 whose localPort matches the port the server uses. Remove externalPort from any other entry.
3. Make sure the deployment run command starts the production server (not a dev server) and that the build command builds the app.
4. Make GET / respond in under 2 seconds at startup: move seeding, migrations and heavy work out of the startup path.
Show me the diff of .replit and the server entry file before you publish.How to verify the fix
- Publishing completes and the deployment shows as live.
curl -I https://your-app.replit.app/returns200(or a redirect) in well under five seconds.- The deployment logs show your own listening on line with the expected port.
- Republishing a second time also succeeds, so the fix is stable.
If the app now goes live but behaves differently from the preview, continue with Replit app works in preview but not after deploy. To pick the right deployment type in the first place, see Autoscale vs Reserved VM vs Static vs Scheduled.
FAQ
Why does my Replit app work in Preview but fail to publish?
Preview runs inside your workspace, where a server on localhost is reachable. A published app runs on separate infrastructure that needs the server on 0.0.0.0, a single external port mapped to 80, and a homepage that answers the health check quickly.
What port should a Replit app use?
Use the PORT environment variable with a fallback such as 5000 or 3000. If your .replit file has a [[ports]] section, the localPort must match that port and the externalPort must be 80.
What does "healthcheck failed: context deadline exceeded" mean?
Replit's check of your homepage did not get an answer in time. Either the server never started listening on the right host and port, or startup work made the first response too slow.