Troubleshooting — Common Errors and Fixes

Most Temps problems leave a clear signal in the logs — start there. Common problems and how to fix them. If you don't find your issue here, check the build logs first — they contain the exact error.

Start here. Pick the line that matches what you're seeing:


Reading logs

Before trying anything else, check the logs:

  • Build logs — Project → Deployments → [deploy] → Build Log
  • Runtime logs — Project → Logs — stdout/stderr from the running container
  • System logs — SSH into your server: journalctl -u temps -f

See Logs for filtering, retention and how build, runtime and proxy logs differ. The CLI commands below are documented in the CLI reference.

# Stream runtime logs via CLI
bunx @temps-sdk/cli runtime-logs --project my-app --follow

# View last 100 lines
bunx @temps-sdk/cli runtime-logs --project my-app --tail 100

Installer errors

These are the messages deploy.sh prints when an install stops. The installer is idempotent: fix the cause, then re-run the same command and it resumes from the step that failed. See the Quickstart for the install flow.

"This script requires bash, which was not found"

The installer is a bash script. Started from sh, dash or zsh it re-launches itself under bash, so this message means bash is not installed at all, which happens on minimal server images. Install it and re-run:

apt-get install -y bash   # Debian / Ubuntu
dnf install -y bash       # RHEL and derivatives
bash deploy.sh

"Interactive prompt '…' needs a terminal"

A prompt had no terminal to read from: the script ran over SSH without a TTY, in CI, or from an agent. Either give it a terminal or answer every prompt up front:

# Interactive, over SSH
ssh -t root@203.0.113.1 'bash /tmp/deploy.sh'

# Headless
bash deploy.sh --mode quick --email you@example.com --yes

Advanced mode can only run headless with --domain, --email and a --dns-provider (cloudflare, route53 or digitalocean) plus its credential. Without a DNS provider, the manual DNS-01 step pauses while you add a TXT record, so it needs a terminal.

"Quick mode with --yes requires --email"

Let's Encrypt needs a contact address and the installer has no fallback for it. Add --email:

bash deploy.sh --mode quick --email you@example.com --yes

"Docker installed but failed to start"

The Docker packages installed, but the daemon did not come up. Check why, then re-run the installer:

sudo systemctl status docker
sudo journalctl -u docker -n 50 --no-pager

If the message is "Docker installation failed" instead, the package install itself failed; the output is in /tmp/temps-wizard-cmd-out.log.

"Cannot continue without a free host port for the database"

The installer runs TimescaleDB in a container on host port 5432. If that port is taken (usually by a PostgreSQL already on the host) it moves to the next free port from 5433 to 5452 on its own. This error means every port in that range is in use. Find what is listening, free one port, and re-run:

sudo ss -ltnp | grep -E ':54[3-5][0-9]'

"The console HTTPS certificate did not provision" (console only reachable over HTTP)

In QuickStart mode the console and each app get a Let's Encrypt certificate the first time their hostname is opened. Let's Encrypt has to reach your server to issue it, so this almost always means inbound port 80 or 443 is blocked:

  1. Open TCP 80 and 443 in your provider's firewall or security group, and in ufw/firewalld if you run one
  2. Behind a router or NAT, forward ports 80 and 443 to this machine. The installer warns "you're likely behind a router/NAT" when the public IP it detects is not the machine's own address
  3. Reload the console URL. The certificate is requested again on the next visit

To see the exact reason, read the issuance log:

sudo journalctl -u temps --no-pager -n 400 | grep on-demand

If the installer reports "Let's Encrypt rate limit" instead, wait and reload, or use your own domain with Advanced mode.


Build errors

npm install fails — ENOTFOUND or registry timeout

The build container can't reach the npm registry:

  1. Check outbound internet access: curl -I https://registry.npmjs.org
  2. If behind a firewall, add the registry to the allowlist
  3. Consider a private registry or caching proxy

Cannot find module after install

A package listed in devDependencies is used at runtime — move it to dependencies. Or your .dockerignore excludes files that are needed at runtime.

Build exceeds memory limit

# Increase Node.js heap in the build step
RUN NODE_OPTIONS="--max-old-space-size=4096" npm run build

Or increase the limit under Project → Settings → Build Resources.

Multi-stage build — COPY --from file not found

The source path must match exactly what the builder stage produced. Add RUN ls /app in the builder stage to verify paths.


Deployment errors

Container starts then immediately exits

The container is crashing on startup. Check runtime logs. Common causes:

  • Missing environment variable — app throws on startup if a required var is absent
  • Port mismatch — app binds to 127.0.0.1 instead of 0.0.0.0
  • Wrong start command — CMD in the Dockerfile doesn't match your entry point

Health check failing

  1. Check Project → Logs for startup errors
  2. Temporarily disable the health check to confirm the app starts at all
  3. Ensure the health check path exists and doesn't require authentication

Deployment stuck at "Waiting for container"

# Redeploy via CLI
bunx @temps-sdk/cli deploy --project my-app

Runtime errors

502 Bad Gateway

The proxy can't reach your container:

  • Container crashed — check logs for a panic or uncaught exception
  • App is listening on the wrong port — ensure PORT env var is used and bound to 0.0.0.0
  • Out of memory — check Project → Metrics for OOM restarts, then raise the memory limit (see Resources and Scaling)

504 Gateway Timeout

Container reachable but not responding within 30s:

  • Slow database query — enable slow query logging and add indexes
  • External API call blocking the event loop
  • CPU-bound work on the main thread — offload to a worker

Environment variables not updating

Variables set after the last deploy are not live until you trigger a new deploy.


SSL / domain issues

Certificate not provisioning

Let's Encrypt requires port 80 to be publicly reachable for the HTTP-01 challenge (see Domains & SSL for how certificates are issued and renewed):

  1. Confirm DNS A record points to the correct server IP
  2. Test port 80: curl -I http://yourdomain.com
  3. Ensure no CDN is intercepting with full-proxy mode enabled

Retry from Project → Settings → Domains → [domain] → Retry.

ERR_TOO_MANY_REDIRECTS

Your app is issuing an HTTP redirect when the proxy already handles HTTPS. Trust the X-Forwarded-Proto header:

// Express
app.set('trust proxy', 1);

DNS not propagating

Propagation can take up to 48 hours (usually under 10 minutes with a low TTL). Check at dnschecker.org.

"No deployment is routed to this host" (branded 404)

If you open a domain and see a Temps-branded page titled "No deployment is routed to this host" with a DEPLOYMENT_NOT_FOUND · 404 chip, the proxy received your request but no app is bound to that host. The page shows the requested Host and a Request ID for support log correlation.

This is expected in two situations:

  • DNS still propagating — you just pointed a domain at the server, but the host isn't yet associated with a deployment. Add the domain under Project → Settings → Domains (see Add a custom domain) and wait for propagation.
  • Hitting the server by an unrecognized hostname — for example the raw server IP or a stale CNAME. The proxy serves this 404 specifically when the host has no route and the request comes from a non-admin client (the admin gate keeps the management console invisible from such hosts).

The response is HTTP 404 with these headers:

HeaderValue
Content-Typetext/html; charset=utf-8
Cache-Controlno-store
X-Request-IDthe request ID shown on the page

When filing a support request, include the Request ID from the page (or the X-Request-ID response header) — it matches the proxy log line admin gate denied request to non-admin host. To fix it, confirm the domain is added to a project and that DNS resolves to your server.


Database issues

Connection refused to localhost:5432

Your app is connecting to localhost but the database is in a separate container. Link the service to your project and use the connection string Temps injects (POSTGRES_URL for PostgreSQL) instead. See Managed PostgreSQL.

Too many connections

Each replica opens its own pool. With many replicas, you exceed PostgreSQL's max_connections (default 100). Reduce pool size per replica:

const pool = new Pool({ connectionString: process.env.POSTGRES_URL, max: 5 });

Or add PgBouncer as a connection pooler.


Upgrade errors

"No stable releases found"

Every Temps release so far is a v0.1.0 prerelease, so the default stable channel of temps upgrade has nothing to install. On v0.1.0-beta.56 and earlier the command also only reads the newest 20 GitHub releases, which are currently all nightly builds, so --channel beta fails too, with "No releases found.". Pin the release you want instead:

temps upgrade --version v0.1.0-beta.56

A pinned --version skips the channel lookup entirely. temps upgrade --channel nightly also works if you want daily builds from main. See Upgrade Temps for the full upgrade flow and how to roll back.


Getting more help

# Run diagnostics
temps doctor

Post in the Discord community with the diagnostics output attached. Questions about servers, pricing, upgrades and backups are answered in the FAQ.

Last updated

Was this page helpful?