Skip to content

Debug Failed Deploys

This tutorial shows the recovery loop for failed BeamUp deploys. The goal is not to guess infrastructure state. The goal is to use the failure category, linked logs, local reproduction, and a focused fix.

BeamUp only moves the active deployment pointer after a candidate runtime passes health checks. If a new deploy fails, the previous healthy deployment remains active.

Run:

Terminal window
beamup --app hello-gleam status

Look for:

  • Latest deployment ID.
  • Latest deployment state.
  • Failure category.
  • Failure summary.
  • Active deployment ID.
  • Whether the active deployment stayed unchanged.

Keep the deployment ID. You will need it for build logs and runtime logs.

Step 2: Decide Whether It Failed Before Or After Build

Section titled “Step 2: Decide Whether It Failed Before Or After Build”

Build-time failures usually need build logs:

Terminal window
beamup --app hello-gleam logs --build --deployment <deployment-id> --no-follow

Runtime or health failures usually need runtime logs:

Terminal window
beamup --app hello-gleam logs --deployment <deployment-id> --no-follow

If you are unsure, fetch both. Logs are scoped to your app and deployment.

Failure category:

missing_gleam_toml

What it means:

BeamUp could not find gleam.toml at the project root or configured app_root.

Fix:

  1. Run from the Gleam project root, or edit app_root.
  2. Make sure the app_root directory contains gleam.toml.
  3. Re-run config validation through deploy.

Example:

app_root = "."

For a nested app:

app_root = "services/web"

Then redeploy:

Terminal window
beamup deploy

Failure category:

unsupported_target

What it means:

The app is not an Erlang-targeted Gleam app under the SLC v1 support boundary.

Fix:

  1. Open gleam.toml.
  2. Use target = "erlang" or omit the target.
  3. Confirm the app builds with gleam export erlang-shipment.

SLC v1 does not support JavaScript-targeted Gleam, Cloudflare Worker-targeted Gleam, Lustre/full-stack hosting, Elixir/Phoenix apps, or non-Gleam Erlang apps.

Failure category:

invalid_config

What it means:

beamup.toml has a field BeamUp cannot accept. The error should name the field.

Common fixes:

  • health must be a path such as /healthz, not a full URL.
  • start must be an array of strings, not a shell string.
  • runtime must be erlang.
  • build.target must be erlang.
  • deploy.strategy must be blue_green.
  • Unknown fields should be removed.
  • Secrets should not be placed in beamup.toml.

Valid start command:

start = ["./build/erlang-shipment/entrypoint.sh", "run"]

Invalid shell string:

start = "./build/erlang-shipment/entrypoint.sh run"

Failure category:

compile_failure

What it means:

The cloud build could not complete the Gleam export path.

Fetch build logs:

Terminal window
beamup --app hello-gleam logs --build --deployment <deployment-id> --no-follow

Then reproduce locally:

Terminal window
gleam test
gleam export erlang-shipment

Fix the compile error, commit or save the source change, then redeploy:

Terminal window
beamup deploy

Failure category:

missing_env_var

What it means:

The app started in the managed runtime but required an env var or secret that was not configured.

Set the value:

Terminal window
beamup --app hello-gleam env set FEATURE_FLAG=enabled

For a secret:

Terminal window
beamup --app hello-gleam env set DATABASE_URL=<database-url> --secret

Do not paste real secret values into issue comments, screenshots, chats, or recorded terminal output.

Configuration applies to future runtime starts. Redeploy after setting a value that the app reads at startup:

Terminal window
beamup deploy

Failure category:

port_binding_failure

What it means:

The runtime did not bind HTTP traffic to the provided PORT.

Check locally:

Terminal window
PORT=8000 ./build/erlang-shipment/entrypoint.sh run
curl -i http://127.0.0.1:8000/healthz

Fix the app so it:

  • Reads PORT from the environment.
  • Parses it as an integer.
  • Binds on 0.0.0.0:<PORT>.

Then redeploy.

Failure category:

startup_failure

What it means:

The runtime process exited or failed before it became healthy.

Fetch runtime logs:

Terminal window
beamup --app hello-gleam logs --deployment <deployment-id> --no-follow

Check:

  • The start command in beamup.toml.
  • Whether the exported shipment exists after build.
  • Whether the app crashes during initialization.
  • Whether required runtime configuration is missing.

Run the exact start command locally with PORT set, then redeploy after the fix.

Failure category:

health_check_failure

What it means:

The app process started, but the configured health path did not return HTTP 2xx.

Check the configured health path:

health = "/healthz"

Check locally:

Terminal window
curl -i http://127.0.0.1:8000/healthz

Fix the handler so it returns HTTP 2xx when the process is ready for traffic. Avoid making the health path depend on every external service unless that is really required for safe activation.

Failure category:

unknown_error

What it means:

BeamUp could not classify the failure into a known category.

Do this:

  1. Keep the request ID or deployment ID from the output.
  2. Fetch build logs.
  3. Fetch runtime logs.
  4. Check the dashboard deployment detail.
  5. Record what command you ran and what the app shape is.

Do not paste tokens, beta codes, secret values, private source, or confidential logs into a public issue or chat.

After any failed deploy, run:

Terminal window
beamup --app hello-gleam status

Confirm whether the previous healthy deployment is still active. Failed builds, startup failures, port failures, and health-check failures should not replace a healthy active deployment.

If the failure happened before activation, fix the issue and redeploy:

Terminal window
beamup deploy

If a healthy deployment was activated but you need to return to a previous version, roll back:

Terminal window
beamup --app hello-gleam rollback

Or choose a specific eligible deployment:

Terminal window
beamup --app hello-gleam rollback --to <deployment-id>

For each failed deploy, record:

  • Command you ran.
  • App shape and framework.
  • Failure category.
  • Whether the summary was actionable.
  • Which logs you opened.
  • Whether the previous active deployment stayed active.
  • Whether founder help was needed.
  • What change fixed the issue.

For reference details, see Logs And Debugging, Rollback, and Supported Apps And Limitations.