Documentation · Operating in production

Troubleshooting: symptom to cause

The failures that come up repeatedly, ordered by how often they are the answer — starting with the container that will not start.

Updated 2026-09-25 · 7 min read

Almost every deployment problem is one of a small number of recurring mistakes. This page lists them in rough order of how often they are the actual cause.

The container will not start

Console shows command not found. The startup command names a file that is not there. Check the path: uploaded projects are frequently one directory deeper than the command assumes.

Console shows a module or package missing. Dependencies are not installed. Run the install once via the console, then start the app directly — see Deploying a Node.js application.

Process starts, exits immediately. An unhandled error, or a script with nothing to keep it running. Read the traceback in the console; it names the line.

Nothing in the console at all. Output is buffered, and the app may be running fine. Check whether the container status shows running before assuming failure.

Running but unreachable

This is the most common problem of all, and it is nearly always the same mistake.

# Wrong
app.listen(3000, "localhost")

# Right
app.listen(3000, "0.0.0.0")

Python: Flask without host="0.0.0.0". Uvicorn without --host 0.0.0.0. Go: localhost:port rather than :port.

Confirm by reading the console: if the logged address contains 127.0.0.1 or localhost, the app is unreachable from outside regardless of anything else you fix.

503 or connection refused

The proxy reached the container but nothing answered. In order: the container is stopped; the app listens on the wrong port; or the app is listening on localhost. Check container status first — it distinguishes "not running" from "running but unreachable" immediately.

Browser warns about the certificate

Usually the custom domain was added before DNS resolved, or a record still points elsewhere. Check that the record resolves, then allow time for issuance and re-check. If the subdomain is in use, that certificate is managed for you.

Out of memory restarts

The container is killed when it exceeds its limit, with no JavaScript traceback — the kernel does not give your runtime the chance to fail gracefully.

Check the memory graph first. Rising memory is a leak; high-but-flat memory needs a bigger plan. If the runtime manages its own heap, cap it below the container limit so it can collect before the kernel intervenes. Also check whether you are running a database inside the same container — see Working with databases.

Changes are not taking effect

Four separate causes, in likelihood order:

  1. The process was not restarted. Uploading a file does not reload it. Restart the service.
  2. The wrong copy is running. Files are one level deeper than the command expects, so you edited a copy that is never read.
  3. A stale process holds the port. Check for a second instance before changing anything else.
  4. A cache. Browser cache, or a build artefact your deploy does not rebuild.

Webhooks never arrive

Confirm the endpoint answers over HTTPS with a 200, from outside. Then check that your handler returns quickly — most webhook senders give you a short timeout and will not retry a slow response. Acknowledge first, process afterwards.

If you terminate TLS at your own service, confirm the certificate chain is complete. An incomplete chain fails verification in some clients and works in others, which makes this look intermittent.

Scheduled tasks not running

Check the schedule's log — output is recorded there, and a task failing for weeks looks identical to one that never ran. Also confirm the timezone assumption: a job that fires at a different hour than you expect is usually a timezone mismatch rather than a missing run. See Scheduled tasks and cron.

A method that works

Read the Console first, every time. A stack trace names the file and line; a listening address tells you whether the network is the problem. Then work outwards:

  1. Console output — is the problem in your code?
  2. Container status — running, or stopped?
  3. Startup command — does it match the entry point?
  4. Listening address — all interfaces, or loopback?
  5. Port — does it match the one assigned to the service?

Each step rules out a layer, and the answer is almost always in the first two.

Still stuck? Open a ticket with the console output attached — it is the single most useful thing you can include, and it turns a long exchange into one message.

These guides describe behaviour that is common across container platforms. Where a setting is specific to your service — your assigned port, your SFTP credentials, your startup command — it is shown in the panel rather than here, so check the Startup and Files tabs for your own values.

Found an error or something unclear? Let us know so we can correct it.