Step 1: Read the right log line
Open Publishing → Logs and scroll to the first ERROR or FAILED line. The last line is usually just the timeout that followed it.
Step 2: "A port configuration was specified but the required port was never opened"
Your server didn't start listening in time, which usually means something crashed or hung before listen().
- Bind to all interfaces and use the provided port:
TypeScript const PORT = Number(process.env.PORT) || 5000; app.listen(PORT, "0.0.0.0", () => console.log("listening", PORT)); - Check that
.replitmaps the local port (e.g. 5000) to external port 80. - Start listening first, then connect to the database and SDKs, with a log line per step.
- Add crash logging so the real error shows up:
TypeScript process.on("unhandledRejection", e => console.error("unhandled", e)); process.on("uncaughtException", e => console.error("uncaught", e)); - Make sure the server responds to
GET /quickly. Health checks hit it.
Step 3: Production secrets are missing
Secrets in the workspace aren't automatically available to the published app. Open the Publishing settings and confirm every key your app reads (database URL, API keys, auth secrets) is set there too. A secret added recently in development is the usual culprit.
Step 4: "Failed to check for database diff: the endpoint has been disabled"
- Open the Database panel → Production and unpause the database if that option appears.
- If you added your own
DATABASE_URLsecret, it can conflict with the Replit-managed one. Rename it (don't delete it) and republish. - Export a copy of your production data before retrying anything.
Step 5: Wrong deployment type
- Static only serves files. If your app has a server, auth or a database, use Autoscale or Reserved VM.
- "Could not find public directory" on Static means the output folder (often
dist) is wrong.
Step 6: Stuck in a publish loop
Shut down the existing deployment from the Manage tab, then publish again. This resets the deployment record.
Step 7: Check the live app, not just the badge
"Published" means the deploy succeeded, not that the app works. Open the live URL in incognito with the console open, and test the pages that use the database.
Run a free ReplayWatch scan. Paste your live URL and ReplayWatch checks it for page load, security headers, secrets exposed in your HTML/JS, Supabase/Firebase data that is readable without login, broken links and assets, SEO tags, and whether your signup page is reachable. It does not log in or run your signup flow. → https://replaywatch.com/#scan