basecamp/kamal · critical · Kamal::Cli::BootError

Failed to get endpoint for #{role} on #{host}, did the conta

Error message

Failed to get endpoint for #{role} on #{host}, did the container boot?

What it means

During `kamal deploy`, Kamal::Cli::App::Boot#start_new_version uploads secrets, runs the new app container, and — for roles configured with proxy: true — must find the new container id to register it as the proxy's traffic endpoint. It captures `app.container_id_for_version(version)`; if that returns an empty string, the freshly run container is not running (it exited or failed to start), so Kamal raises Kamal::Cli::BootError, logs 'Failed to boot <role> on <host>', and the deploy aborts before old containers are stopped.

Source

Thrown at lib/kamal/cli/app/boot.rb:56

        info "Renaming container #{version} to #{renamed_version} as already deployed on #{host}"
        audit("Renaming container #{version} to #{renamed_version}")
        execute *app.rename_container(version: version, new_version: renamed_version)
      end

      capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip.presence
    end

    def start_new_version
      audit "Booted app version #{version}"
      hostname = "#{host.to_s[0...51].chomp(".")}-#{SecureRandom.hex(6)}"

      execute *app.ensure_env_directory
      upload! role.secrets_io(host), role.secrets_path, mode: "0600"

      execute *app.run(hostname: hostname)
      if running_proxy?
        endpoint = capture_with_info(*app.container_id_for_version(version)).strip
        raise Kamal::Cli::BootError, "Failed to get endpoint for #{role} on #{host}, did the container boot?" if endpoint.empty?
        execute *app.deploy(target: endpoint)
      else
        Kamal::Cli::Healthcheck::Poller.wait_for_healthy { capture_with_info(*app.status(version: version)) }
      end
    rescue => e
      error "Failed to boot #{role} on #{host}"
      raise e
    end

    def stop_new_version
      execute *app.stop(version: version), raise_on_non_zero_exit: false
    end

    def stop_old_version(version)
      execute *app.stop(version: version), raise_on_non_zero_exit: false
      execute *app.clean_up_assets if assets?
      execute *app.clean_up_error_pages if KAMAL.config.error_pages_path
    end

View on GitHub (pinned to eee0083b38)

Solutions

  1. Get the boot failure details: `kamal app logs -r <role> -h <host>` (the error message names the role and host) — fix the crash shown there.
  2. Reproduce on the host: ssh in and run `docker ps -a --filter name=<service>-<version>` then `docker logs <id>` to see the exact exit reason.
  3. Check the role's secrets/env for the destination (`kamal app secrets` style inspection) and confirm the secrets file exists with mode 0600 on the host.
  4. After fixing, re-run `kamal deploy`; the failed new version is stopped by stop_new_version, so old version keeps serving.
  5. If the image itself is broken, roll back the build: redeploy a previous version with `kamal deploy --version <old>` or fix and push a new image.

Example fix

# before: deploy fails with BootError, container exits instantly
kamal deploy
# after: diagnose the exited container on the failing host first
kamal app logs -r web -h 203.0.113.10
ssh app@203.0.113.10 'docker ps -a --filter name=myapp- | head; docker logs $(docker ps -aq --filter name=myapp- | head -1)'
# fix entrypoint/secrets in config, then:
kamal deploy
Defensive patterns

Strategy: try-catch

Validate before calling

# Smoke-test bootability before deploying: run the image locally with the same env
# docker run --rm --env-file .kamal/secrets.<role> <image> <entrypoint> --check || echo 'will fail boot'

Type guard

def image_boots?(image, env = {})
  env_args = env.map { |k, v| "-e #{k}=#{v}" }.join(" ")
  system("docker run --rm #{env_args} #{image} true")
end

Try / catch

begin
  Kamal::CLI::Deploy.new.perform # wraps App::Boot#start_new_version
rescue Kamal::Cli::BootError => e
  warn "boot failed: #{e.message} — old version still serving"
  `kamal app logs -r #{role}` # gather evidence; deploy already stopped the bad version
  raise
end

Prevention

When it happens

Trigger: `kamal deploy` (or `kamal app boot`) on a role with running_proxy? true where `docker run` succeeded as a command but the container immediately exits: bad entrypoint, missing secret file uploaded with wrong content, crashed process, missing image on the host, or a name/hostname collision. The rescue block re-raises after logging, failing the whole deploy.

Common situations: First deploy of a role whose image entrypoint references a missing env var; secrets template renders empty so the app raises on boot; role uses kamal proxy labels but container port is wrong; host out of disk so docker run fails silently; stale docker images after a registry migration.

Related errors


AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21). Data as JSON: /api/errors/1980c532b240a639. Report an issue: GitHub.